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
",i);break;}
    }
    return 0;
}
原文地址:https://www.cnblogs.com/VIrtu0s0/p/10815459.html