hdu 6495 dp

http://acm.hdu.edu.cn/showproblem.php?pid=6495

题意

有n个挑战(1e3),假如接受,在挑战之前体力x会变成min(x,\(b[i]\)),然后会减去a[i],无论是否接受这个挑战,体力在结束后都会增加\(c[i]\),问最多能完成多少个挑战

题解

  • 定义\(dp[i][j]\)为前i个挑战接受了j个后剩下的最大体力
    • 接受:\(min(dp[i-1][j-1],b[i])-a[i]+c[i]\);
    • 不接受:\(dp[i-1][j]+c[i]\)
  • 体力小于等于0不能转移

代码

#include<bits/stdc++.h>
#define ll long long 
using namespace std;
ll dp[1002][1002],a[1002],b[1002],c[1002];
int n,T;
ll C;
int main(){
    cin>>T;
    while(T--){
        memset(dp,0,sizeof(dp));
        scanf("%d%lld",&n,&C);
        dp[0][0]=C;
        for(int i=1;i<=n;i++){
            scanf("%lld%lld%lld",&a[i],&b[i],&c[i]);
            dp[i][0]=dp[i-1][0]+c[i];
            for(int j=1;j<=i;j++){
                ll tp;
                if(min(dp[i-1][j-1],b[i])<=a[i])tp=0;
                else tp=min(dp[i-1][j-1],b[i])-a[i]+c[i];
                if(j<i&&dp[i-1][j])dp[i][j]=max(dp[i-1][j]+c[i],tp);
                else dp[i][j]=tp;
            }
        }
        for(int i=n;i>=0;i--)if(dp[n][i]>0){printf("%d\n",i);break;}
    }
    return 0;
}
上一篇:百炼OJ - 1002 - 方便记忆的电话号码


下一篇:PTA 1002 写出这个数