#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!