#include <bits/stdc++.h>
using namespace std;
const int MN=1010;
int N, V;
int v[MN], w[MN], f1[MN], f2[MN]; //f1/2[V]表示容量不超过/恰好等于V的最大价值
int main()
{
cin>>N>>V;
memset(f2, -1, sizeof f2);
f2[0]=0;
for(int i=1;i<=N;i++) cin>>v[i]>>w[i];
for(int i=1; i<=N; i++)
for(int j=v[i]; j<=V; j++)
{
f1[j]=max(f1[j], f1[j-v[i]]+w[i]);
if(f2[j-v[i]]!=-1) f2[j]=max(f2[j], f2[j-v[i]]+w[i]);
}
f2[V]=max(0, f2[V]);
cout<<f1[V]<<"\n"<<f2[V];
return 0;
}
/*
f[i , j ] = max( f[i-1,j] , f[i-1,j-v]+w , f[i-1,j-2*v]+2*w , f[i-1,j-3*v]+3*w , .....)
f[i , j-v]= max( f[i-1,j-v] , f[i-1,j-2*v] + w , f[i-1,j-3*v]+2*w , .....)
可推导出 f[i,j]=max(f[i-1,j], f[i][j-v]+w[i])
*/
/*int main()
{
cin>>N>>V;
for(int i=1;i<=N;i++) cin>>v[i]>>w[i];
for(int i=1;i<=N;i++)
for(int j=0;j<=V;j++)
for(int k=0; 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][V];
return 0;
}*/
第一问就是完全背包的裸题,推导可以看注释代码
第二问可以初始时只让f2[0]合法,转移时避免了从非法状态转移过了
即可愉快ac!

京公网安备 11010502036488号