5662 纪念品
为啥没做过这个?
不知道,可能觉得很难吧
没关系,现在来做做
t天之后,小伟的超能力就会消失,他要在这t天之内卖出所有的纪念品
所以,很明显,这就是一个动态规划问题
但是状态呢,怎么玩状态?状态貌似在这个题目中很好突破也很变态
于是我们定义一个数组f[i][j][k]来记录第i天,考虑到第j个物品1,手里面还有第k元的时候,明天早上能卖掉的最大的金币数量,然后就类似于背包的思路了
我们用prise[i][j]表示第i天第j个物品的价格
那么方程式就是f[i][j][k]=max(f[i][j][k],f[i][j-1][k+prise[i][j]]+price[i+1][j]-price[i][j]),表示第j个物品如果要了,手里的现金就会少了price[i][j],但是期望明天早上的收益也多了price[i+1][j]-price[i][j],为何如此,因为这是差价
j循环一遍以后,在收益里面取最大值,变成明天的金币就好了
但是三个维度肯定会炸
所以,我们可以把i给省略压缩掉了
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAXN = 105;
//dp[k]表示手里剩k元,明天早上都卖了以后的钱数
//price[i][j]表示第i天第j件物品的价格
int dp[10005], price[MAXN][MAXN];
int main()
{
int t, n, m, ans;
scanf("%d%d%d", &t, &n, &m);
for (int i = 1; i <= t; ++i)
{
for (int j = 1; j <= n; ++j)
{
scanf("%d", &price[i][j]);
}
}
ans=m;//手上现有m元
for (int i=1;i<t;i++)
{
//先把数组赋值为负无穷
memset(dp, ~0x3f, sizeof(dp));
//什么都不买
dp[ans]=ans;
for (int j=1;j<=n;j++)
{
//手里有k元的时候,去推明天早上的钱
for (int k = ans; k >= price[i][j]; --k)
{
//买这件物品
dp[k - price[i][j]] = max(dp[k - price[i][j]], dp[k] + price[i + 1][j] - price[i][j]);//买的价值,和不买的价值
}
}
int ma = 0;
for (int j=0;j<=ans;j++)
{
ma=max(ma, dp[j]);
}
//继续比较,比较最大的
ans=ma;
}
cout<<ans<<endl;
return 0;
}