acm专项训练-----第十一届山东省程序设计竞赛h题Adventurer's Guild
很典型的二维背包问题,但是有几个坑点需要注意,看,这就是踩坑的下场:
题目的大意是:
一个人打怪升级,他身上有耐力度和健康度,一旦健康度<=0就挂了,但耐力度不一样,只要耐力度在健康度的承受范围内:
举个例子,这个人打完怪耐力度是-3,但健康度是4,他就不会死,给点n个怪,杀死这些怪可以获得金币,问在保证不死的前提之下获得最多的金币;
当然,这个题用二维背包解就可以了;
但是需要注意的是:
体力小于0就重置为0,
永远保证生命值>0,
数据的范围是1e^9;
体力小于0要单独处理,因为j,k不能同时根据情况变化;
Talk is cheap. Show me the code.
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int num=1010; 4 int n,h,s; 5 int a[num]; 6 int b[num]; 7 long long c[num];//1e9很大了 8 long long dp[num][num];//1e9很大了 9 int main() 10 { 11 std::ios::sync_with_stdio(false); 12 cin.tie(0); 13 cout.tie(0); 14 cin>>n>>h>>s; 15 for(int i=1;i<=n;i++) 16 cin>>a[i]>>b[i]>>c[i]; 17 for(int i=1;i<=n;i++) 18 { 19 for(int j=h;j>a[i];j--)//不要等于,一旦等于就是挂 20 { 21 for(int k=s;k>=0;k--) 22 { 23 if(k-b[i]<0)//耐力度小于0的情况 24 { 25 if(j-a[i]+k-b[i]>0)//保证生命不死 26 dp[j][k]=max(dp[j][k],dp[j-a[i]+k-b[i]][0]+c[i]);//体力小于0重置 27 } 28 else//其他情况直接按二维背包正常处理即可 29 { 30 dp[j][k]=max(dp[j][k],dp[j-a[i]][k-b[i]]+c[i]); 31 } 32 } 33 } 34 } 35 cout<<dp[h][s]<<endl; 36 return 0; 37 }
本文来自博客园,作者:江上舟摇,转载请注明原文链接:https://www.cnblogs.com/LQS-blog/p/16213312.html