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 }

 

posted @ 2022-05-01 17:05  江上舟摇  阅读(50)  评论(0编辑  收藏  举报