一个旅行者有一个最多能装 M M M公斤的背包,现在有 N N N件物品,他们的重量分别是 W 1 W_1 W1, W 2 W_2 W2, W 3 W_3 W3, . . . ... ..., W n W_n Wn,价值分别为 C 1 C_1 C1, C 2 C_2 C2, C 3 C_3 C3, . . . ... ..., C n C_n Cn,求旅行者能获得的最大价值.
第 1 1 1行,两个整数, M , N M,N M,N
第 2 2 2至 N + 1 N+1 N+1行,每行两个整数 W i , C i W_i,C_i Wi,Ci,表示每个物品的重量和价值.
设 F [ i ] [ v ] F[i][v] F[i][v]表示当前进行到第 i i i件物品,总重量小于等于 v v v的最大价值.故转移方程可以这样写: F [ i ] [ v ] = m a x ( f [ i − 1 ] [ v ] , f [ i − 1 ] [ v − w [ i ] ] + c [ i ] ) F[i][v]=max(f[i-1][v],f[i-1][v-w[i]]+c[i]) F[i][v]=max(f[i−1][v],f[i−1][v−w[i]]+c[i]) 最后输出 F [ n ] [ m ] F[n][m] F[n][m].
我们会发现,每一次, i i i没有参与什么实质性的运算,所以,我们可以考虑删掉 i i i,只保留 v v v,其中, F [ v ] F[v] F[v]表示重量小于等于 v v v可获得的的最大价值.
所以,动态转移方程为: F [ v ] = m a x ( f [ v ] , f [ v − w [ i ] ] + c [ i ] ) F[v]=max(f[v],f[v-w[i]]+c[i]) F[v]=max(f[v],f[v−w[i]]+c[i]),当且仅当 v > w [ i ] , 1 ≤ i ≤ n v>w[i],1≤i≤n v>w[i],1≤i≤n时.
#include
using namespace std;
int m,n;
int w[31];
int c[31];
int f[31][201];
int main()
{
cin>>m>>n;
for(int i=1;i<=n;i++)
cin>>w[i]>>c[i];
for(int i=1;i<=n;i++)
{
for(int v=m;v>0;v--)
{
if(w[i]<=v)
{
f[i][v]=max(f[i-1][v],f[i-1][v-w[i]]+c[i]);
}
else
{
f[i][v]=f[i-1][v];
}
}
}
cout<<f[n][m]<<endl;
return 0;
}
#include
using namespace std;
int m,n;
int w[31];
int c[31];
int f[201];
int main()
{
cin>>m>>n;
for(int i=1;i<=n;i++)
cin>>w[i]>>c[i];
for(int i=1;i<=n;i++)
for(int v=m;v>=w[i];v--)
f[v]=max(f[v],f[v-w[i]]+c[i]);
cout<<f[m]<<endl;
return 0;
}