P1802 5倍经验日(dp)
给出几个好友、几瓶药水,和每个好友战斗输了得到的经验值、赢了的经验值、赢了需要消耗至少几瓶药水,求最后得到的最大经验值(结果*5,longlong)
输入:
6 8 21 52 1 21 70 5 21 48 2 14 38 3 14 36 1 14 36 2
输出:1060
这题转化为01背包模型,每个好友都是输或者赢两种情况之一,第一维代表考虑多少个好友、第二维代表当前有几个药水。
列出方程dp[i][j]=max(dp[i-1][j]+a[i].lose,dp[i-1][j-a[i].use]+a[i].win);
#include<iostream> #include<algorithm> #include<vector> #include<queue> using namespace std; typedef long long int ll; struct node{ ll lose,win,use; }a[1005]; vector<vector<ll> >dp(1005,vector<ll>(1005)); int main() { int n,k,maxx=-1;cin >> n>>k; for (int i = 0;i < n;i++){ cin >> a[i].lose>>a[i].win>>a[i].use; maxx=max(a[i].use,maxx); } for (int i = 0;i < n;i++) { for (int j = 0;j <=maxx;j++) { dp[i][j] = 0; } } for(int i=a[0].use;i<=maxx;i++)dp[0][i] =a[0].win; for(int i=0;i<a[0].use;i++)dp[0][i]=a[0].lose; for (int i = 1;i < n;i++) { for (int j = 0;j <= k;j++) { if (j >= a[i].use) { dp[i][j] = max(dp[i - 1][j]+a[i].lose, dp[i-1][j - a[i].use]+a[i].win); } else dp[i][j] = dp[i - 1][j]+a[i].lose; } } /*for (int i = 0;i < n;i++) { for (int j = 0;j <= k;j++) { cout << dp[i][j] << " "; } cout << endl; }*/ //类似01背包 cout << dp[n - 1][k]*5 << endl; return 0; } /* 6 3 34 4 12 5 2 9 */