我的做法:分完全背包,和多重背包两种情况,朴素做法,三重循环(TLE了)
#include <iostream>
using namespace std;
const int N=1010;
int f[N][N];
int v[N],w[N],s[N],st[N];
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int a,b,c;
cin>>a>>b>>c;
v[i]=a;
w[i]=b;
if(c==-1)
s[i]=1;
else if(c==0)
st[i]=1;
else
s[i]=c;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
f[i][j]=f[i-1][j];
for(int k=1;(k<=s[i]||st[i])&&k*v[i]<=j;k++)
{
f[i][j]=max(f[i][j],f[i-1][j-k*v[i]]+k*w[i]);
}
}
}
cout<<f[n][m];
return 0;
}
优化1:空间优化(还是会TLE
#include <iostream>
using namespace std;
const int N=1010;
int f[N];
int v[N],w[N],s[N],st[N];
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int a,b,c;
cin>>a>>b>>c;
v[i]=a;
w[i]=b;
if(c==-1)
s[i]=1;
else
s[i]=c;
}
for(int i=1;i<=n;i++)
{
if(s[i]==0)
{
//不知道为什么,这里一定要改成j=v[i],不能是j=1
for(int j=v[i];j<=m;j++)
{
f[j]=max(f[j],f[j-v[i]]+w[i]);
}
}
else
{
for(int j=m;j>=v[i];j--)
{
for(int k=1;k<=s[i]&&k*v[i]<=j;k++)
{
f[j]=max(f[j],f[j-k*v[i]]+k*w[i]);
}
}
}
}
cout<<f[m];
return 0;
}
优化2:二进制优化多重背包
#include <iostream>
using namespace std;
const int N=1010;
int f[N];
int v[N],w[N],s[N],st[N];
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int a,b,c;
cin>>a>>b>>c;
v[i]=a;
w[i]=b;
if(c==-1)
s[i]=1;
else
s[i]=c;
}
for(int i=1;i<=n;i++)
{
if(s[i]==0)
{
//不知道为什么,这里一定要改成j=v[i],不能是j=1
for(int j=v[i];j<=m;j++)
{
f[j]=max(f[j],f[j-v[i]]+w[i]);
}
}
else
{
for(int k=1;k<=s[i];k=k*2)
{
for(int j=m;j>=k*v[i];j--)
{
f[j]=max(f[j],f[j-k*v[i]]+w[i]*k);
}
s[i]-=k;
}
if(s)
{
for(int j=m;j>=s[i]*v[i];j--)
{
f[j]=max(f[j],f[j-s[i]*v[i]]+s[i]*w[i]);
}
}
}
}
cout<<f[m];
return 0;
}