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;
}