<USACO07JAN>解决问题Problem Solvingの思路

日常为dp贡献脑细胞

 1 #include<iostream>
 2 #include<cmath>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<algorithm>
 7 using namespace std;
 8 int dp[310][310],fst[310],lst[310];
 9 int n,p;
10 int main()
11 {
12     int i,j,k;
13     memset(dp,5,sizeof(dp));
14     scanf("%d%d",&n,&p);
15     for(i=1;i<=p;i++)scanf("%d%d",&fst[i],&lst[i]);
16     dp[1][1]=1;dp[1][0]=2;dp[0][0]=0;
17     for(i=1;i<=p;i++)
18     {
19         fst[i]+=fst[i-1];lst[i]+=lst[i-1];//前缀和方便算几个任务一共的钱 
20     }
21     for(i=2;i<=p;i++)//总共已完成的
22     {
23         //本月完成任务!! 
24         for(j=1;j<=i;j++)//本月完成的
25         {
26             for(k=0;k<=i-j;k++)//上月完成的(欠了多少 
27             {
28                 if(fst[i]-fst[i-j]+lst[i-j]-lst[i-j-k]<=n)//钱够得话.利用前缀和 算一段任务的钱
29                     dp[i][j]=min(dp[i][j],dp[i-j][k]+1);
30             } 
31         }
32         //本月不完成任务
33         for(k=1;k<=p;k++)if(lst[i]-lst[i-k]<=n)dp[i][0]=min(dp[i][k]+1,dp[i][0]);//就还债 
34     }
35     int ans=dp[p][0]+1;
36     for(i=1;i<=p;i++)//倒二月完成的.最后月还 
37         if(lst[p]-lst[i-p]<=n)ans=min(ans,dp[p][i]+2);
38     printf("%d",ans);
39 return 0;    
40 }

猜你喜欢

转载自www.cnblogs.com/pile8852/p/9278540.html