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),当你完成这个挑战的时候,你的体力会变成 x−ai,体力任何时候不允许小于等于 0,无论你是否接受第 i 个挑战,在这个挑战结束以后你的体力都会增加 ci。
现在我们想知道最多可以完成多少个挑战。
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),当你完成这个挑战的时候,你的体力会变成 x−ai,体力任何时候不允许小于等于 0,无论你是否接受第 i 个挑战,在这个挑战结束以后你的体力都会增加 ci。
现在我们想知道最多可以完成多少个挑战。
Input
第一行一个正整数 T (T≤50) 表示数据组数。
接下来 T 组数据,每组第一行两个正整数 n,c (1≤n≤1e3,1≤c≤1e9),表示挑战的数量和初始体力,接下来 n 行,每行三个非负整数 ai,bi,ci(0≤ai,bi,ci≤1e9)。
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 }