日常为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 }