https://www.luogu.org/problemnew/show/P1616
完全背包,可以用一个常数优化,对于同一个价值的量,仅保存花费最小的那个就行了,因为每种都有无限多个。
#include<bits/stdc++.h>
using namespace std;
int n,V;
int c[10005],w[10005];
int d[100005];
int MinCost[10005],pos;
void CompletePack()
{
for(int i=1;i<=n;i++)
for(int j=c[i];j<=V;j++)d[j]=max(d[j],d[j-c[i]]+w[i]);
}
void init()
{
cin>>V>>n;
int pertime,value;
for(int i=1;i<=n;i++)
{
cin>>pertime>>value;
if(0==MinCost[value])
{
MinCost[value]=++pos;
c[pos]=pertime;
w[pos]=value;
}
else if(pertime<c[MinCost[value]])
{
c[MinCost[value]]=pertime;
w[MinCost[value]]=value;
}
}
n=pos;
}
int main()
{
freopen("input.in","r",stdin);
init();
CompletePack();
cout<<d[V]<<endl;
return 0;
}
后来想快些,看错题本来是每个草药价值小于10000,结果看成草药总价值小于10000,于是想,用p(i,j)表示前i个物品价值为j用的最小花费。
初始化p(0,0)=0,p(0,j)=INF. 状态转移方程p(i,j)=min{p(i-1,j),p(i-1,j-w(i))+c(i)}
最后找最大的时间小于要求的价值就ok了,然后wa了,一组没过,才发现看错了题。