啊,dp,万恶的dp。
本来不想补的,被某人押着说div3这么可以不ak于是不得不补了。真是痛苦的经历。(笑)
题目链接:https://codeforces.com/problemset/problem/1203/F2
题目大意:给定任务个数n和初始值r,完成每个任务需要有ai的r值,完成后r值会改变bi,问最多能完成多少任务(要保证最后r>=0)
思路:首先如果是正值的话自然按照a从小到大排一遍能加的都加上,然后问题在于负值。贪心显然不行,或者说这其实就是个背包问题的轻度转换,首先要做的预处理是对于bi为负值的第i项任务,它的ai=max(ai,-bi)这样才能保证完成这个任务后r不小于0,。然后就是dp,对于dp[i][j],我们认为它代表的是r值为j时,做到第i个任务为止(i已做)完成的最多任务数。那么,假设第i个能做,状态转移方程就是dp[i+1][j+aa[i].delt]=max(dp[i+1][j+aa[i].delt],dp[i][j]+1),aa储存的是所有的负值任务(已排序),这个方程的意思就是,假设能做,那就任务数+1,否则就在下个判断中补回这个任务消耗的r值。
代码如下:
1 #include<set> 2 #include<stdio.h> 3 #include<string.h> 4 #include<math.h> 5 #include<vector> 6 #include<stdlib.h> 7 #include<queue> 8 #include<algorithm> 9 #include<map> 10 #include<stack> 11 using namespace std; 12 struct node 13 { 14 int ned; 15 int delt; 16 int zf; 17 }e[105]; 18 bool cmp(node a,node b) 19 { 20 if(a.zf==b.zf) 21 { 22 if(a.zf==1) 23 { 24 return a.ned<b.ned; 25 } 26 else 27 { 28 return a.ned+a.delt>b.ned+b.delt; 29 } 30 } 31 return a.zf<b.zf; 32 } 33 int main() 34 { 35 int n,r; 36 scanf("%d%d",&n,&r); 37 for(int i=0;i<n;i++) 38 { 39 scanf("%d%d",&e[i].ned,&e[i].delt); 40 if(e[i].delt>=0)//标号1为正 2为负 便于一次性排序 41 { 42 e[i].zf=1; 43 } 44 else 45 { 46 e[i].zf=2; 47 e[i].ned=max(e[i].ned,abs(e[i].delt)); 48 } 49 } 50 sort(e,e+n,cmp); 51 int s=r; 52 /*for(int i=0;i<n;i++) 53 { 54 printf("%d %d %d\n",e[i].ned,e[i].delt,e[i].zf); 55 }*/ 56 int sum=0; 57 vector<node>aa;//储存负值任务 58 for(int i=0;i<n;i++) 59 { 60 if(e[i].zf==1) 61 { 62 if(s>=e[i].ned) 63 { 64 s+=e[i].delt; 65 sum++; 66 } 67 } 68 else 69 { 70 aa.push_back(e[i]); 71 } 72 } 73 vector<vector<int>>dp(aa.size()+1,vector<int>(s+1,0)); 74 dp[0][s]=sum; 75 for(int i=0;i<int(aa.size());i++) 76 { 77 for(int j=0;j<=s;j++) 78 { 79 if(j>=aa[i].ned&&j+aa[i].delt>=0) 80 { 81 dp[i+1][j+aa[i].delt]=max(dp[i+1][j+aa[i].delt],dp[i][j]+1);//假如当前任务可做 82 } 83 dp[i+1][j]=max(dp[i+1][j],dp[i][j]);//推到下一个任务 84 } 85 } 86 sum=0; 87 for(int i=0;i<=s;i++) 88 { 89 //printf("%d\n",dp[int(aa.size())][i]); 90 sum=max(sum,dp[int(aa.size())][i]); 91 } 92 printf("%d\n",sum); 93 return 0; 94 }
原文地址:https://www.cnblogs.com/forever3329/p/11370389.html
时间: 2024-10-29 08:45:04