P5662 纪念品
题目传送门
思路:
核心:完全背包
这道题目是多次的完全背包问题
我们需将题目中的几个条件改一下,就很明确用背包了。
- 背包容量那就看成现在手中金币嘛(会变的)
- 我们可以将利润(当天卖出价格-昨天买进价格)看成价值。
- 重量就是昨天买进价格
然后对于每天的策略:尽量选性价比较高的,当然负利润就可做剪枝(亏本啊~)。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
using namespace std;
const int MAX=2147483647;
const int N=1e6;
int t,n,m,w[N],d[N],v[N],f[N],ans;
int main()
{
//fre();
scanf("%d%d%d",&t,&n,&m);
if(t==1) {printf("%d",m);return 0;} //特判只有一天
for(int i=0;i<n;i++) scanf("%d",&w[i]);
//第一天无售出过程,直接储存其购入价格
for(int i=1;i<t;i++)
{
for(int j=0;j<n;j++)
{
scanf("%d",&d[j]);
v[j]=d[j]-w[j]; //计算收益
}
memset(f,0,sizeof(f));
for(int j=0;j<n;j++)
{
if(v[j]<0) continue; //去掉当天为负收益的物品
for(int c=w[j];c<=m;c++)
f[c]=max(f[c],f[c-w[j]]+v[j]);
}
m+=f[m]; //m每天都有收益,不能用其他变量替代
for(int j=0;j<n;j++) w[j]=d[j];
//“购入-售出”过程结束后将当前的“售出”价格转为次日的“购入”价格
}
printf("%d",m);
return 0;
}