HDU 6495 冰水挑战

Problem Description
Polar Bear Pitching helps you crystallize your message. 
The stage could not be any cooler, and we mean literally: 
a hole cut through the ice in the frozen Baltic Sea.
2050有一项很有挑战的活动 —— Polar Bear Pitching 。
体验人跳入冰水中讲述自己的恐惧,改变以及梦想。这是没有时间限制的演讲,就看你能在冰水中呆多久!
现在,我们要依次面对 n 个冰水挑战,每个挑战你都可以选择接受或不接受。接受第 i 个挑战会让你丧失 ai点体力,因为每个挑战所处的环境不同,如果你要挑战它,在挑战它之前你的体力 x 会变成 min(x,bi),当你完成这个挑战的时候,你的体力会变成 xai,体力任何时候不允许小于等于 0,无论你是否接受第 i 个挑战,在这个挑战结束以后你的体力都会增加 ci
现在我们想知道最多可以完成多少个挑战。
 
Input
第一行一个正整数 T (T50) 表示数据组数。
接下来 T 组数据,每组第一行两个正整数 n,c (1n1e3,1c1e9),表示挑战的数量和初始体力,接下来 n 行,每行三个非负整数 ai,bi,ci(0ai,bi,ci1e9)
 
Output
对于每组数据输出一行一个数,表示你最多能完成几个挑战。
 
题意:给你一定的背包容量,让你求在i个活动中最多可以选择多少个; 
题解:基础的dp问题,确定子问题 在前i中 选j 的背包剩余容量, 
   划分:选择第i个从i-1推,或不选第i个从i-1推; 
注意此题的数据,int是会溢出的,要long long ; 
还有这题的背包容量是在变化的,在到下一个活动的时候,dp[i][0]都会在dp[i-1][0]上增加;

总结:1. f[a][b]=c,当b过大的时候,可以把b c换个位置填表,在返回找满足条件的最大的c,
     2.写dp问题的时候,初始话和边界条件一定要注意再注意,小心再小心!!!
    此题的f初始化为-INF,在转移过程出现负数是不合法的,
尤其注意在状态转移的过程中,状态转移方程触碰的边界是否需要初始化!!!

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 using namespace std;
 5 
 6 const int INF=0x3f3f3f3f;
 7 const int maxn=1e3+5;
 8 long long f[maxn][maxn], a[maxn], b[maxn], c[maxn];
 9 
10 int main()
11 {
12     //freopen("in.txt", "r", stdin);
13     int T; cin>>T;
14     while(T--)
15     {
16         int n,s; cin>>n>>s;
17         for(int i=1; i<=n; i++)
18             cin>>a[i]>>b[i]>>c[i];
19 
20         memset(f, -0x3f, sizeof(f));//状态转移过程中出现负数是不合法的,且取max,故初始化为-INF
21         f[0][0]=s;   //注意边界的初始化
22         for(int i=1; i<=n; i++)
23         {
24             f[i][0]=f[i-1][0]+c[i];  //注意边界的初始化,千万别弄丢了!!!
25             for(int j=1; j<=n; j++)
26             {
27                 long long t1=f[i-1][j]+c[i];        //不选
28                 long long t2=min(f[i-1][j-1], b[i])-a[i]; //
29                 if(t2>0)
30                     f[i][j]=max(t1, t2+c[i]);
31                 else
32                     f[i][j]=t1;
33             }
34         }
35 
36         int ans=0;
37         for(int j=n; j>=0; j--)
38             if(f[n][j]>0){
39                 ans=j; break;
40             }
41         cout<<ans<<endl;
42     }
43     return 0;
44 }

 

 
 
posted @ 2019-04-25 22:54  N_Yokel  阅读(233)  评论(0编辑  收藏  举报