冰水挑战 HDU

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6495

题解:DP!!! dp[i][j] 表示前i个挑战,接受了j个剩余的最大体力,最后输出体力大于0的j最大的即可

#include<iostream>
#include<vector>
#include<algorithm>
#include <cstdio>
#include<cmath>
#include<set>
#include<cstring>
#include<string>
#include<iomanip>
#define INF 0x3f3f3f
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int maxn=1201;
const double PI=acos(-1.0);
ll a[maxn],b[maxn],c[maxn],dp[maxn][maxn];//d[i][j]代表前i个挑战选j个所剩余的最大的体力
int main()
{
    int n,m;
    int t;
    cin >> t;
    while(t--)
    {
        cin >> n >> m;
        for(int i = 1;i <= n;i ++)
        cin >> a[i] >> b[i] >> c[i];
        memset(dp,-INF,sizeof(dp));//初始化
        dp[0][0] = m;//初始体力
        ll tmp;
        for(int i  = 1;i <= n;i ++)
        {
            dp[i][0]=dp[i-1][0]+c[i];
            for(int j = 1;j <= n;j ++)
            {
                dp[i][j] = dp[i-1][j] + c[i];
                tmp = min(dp[i-1][j-1],b[i])-a[i];//每次挑战之前体力取当前体力和b[i]最小的值
                if(tmp > 0)//如果第j个挑战后还有体力
                {
                    dp[i][j] = max (dp[i][j],tmp + c[i]);//该次挑战体力后取最大
                }
            }

        }
        for(int i = n; i >= 0;i --)
        {
            if(dp[n][i] > 0)
            {
                cout << i << endl;break;//如果有找到体力大于0的,该编号就是最大的挑战次数
                
            }
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/kayiko/p/10776842.html