题目传送门
思路
一道变形的01背包。
dp数组含义
dp[i]表示打i罐药的最优解
状态转移方程
这道题要分类讨论,如果我们药的数量够打败这个敌人的话,那么我们就选不打和打的最优解,如果药的数量不够,我们只能不打,所以状态转移方程为:
if(j>=u[i]){
dp[j]=max(dp[j]+l[i],dp[j-u[i]]+w[i]);
}else dp[j]=dp[j]+l[i];
初始化
无需初始化。
推导顺序
因为我们需要考虑j<u[i]的情况,所以我们能蹭循环要遍历到0.
输出
输出5倍的dp[x],这可能会爆int,所以要开long long.
代码
#include<bits/stdc++.h>
#define endl '\n';
using namespace std;
const int N=1e3+10;
long long n,x,l[N],w[N],u[N];
long long dp[N];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>x;
for(int i=1;i<=n;i++){
cin>>l[i]>>w[i]>>u[i];
}
for(int i=1;i<=n;i++){
for(int j=x;j>=0;j--){
if(j>=u[i]){
dp[j]=max(dp[j]+l[i],dp[j-u[i]]+w[i]);
}else dp[j]=dp[j]+l[i];
}
}cout<<dp[x]*5;
return 0;
}