#include <bits/stdc++.h> using namespace std; const int MAXN=1010; int N, V; int v[MAXN], w[MAXN], f[MAXN], dp[MAXN]; int main() { cin>>N>>V; memset(dp, -1, sizeof dp); dp[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; j>=v[i]; j--)//倒序滚动是因为max(f[i-1][j], f[i-1][j-v[i]]+w[i]中j-v[i]一定小于j,此时未更新,用的就是i-1时的数据 { f[j]=max(f[j], f[j-v[i]]+w[i]); if(dp[j-v[i]]!=-1) dp[j]=max(dp[j], dp[j-v[i]]+w[i]); } dp[V]=max(0, dp[V]); cout<<f[V]<<"\n"<<dp[V]; return 0; } /*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++) if(j<v[i]) f[i][j]=f[i-1][j]; else f[i][j]=max(f[i-1][j], f[i-1][j-v[i]]+w[i]); cout<<f[N][V]; return 0; }*/
第一问就是01背包,在代码中下面给出了二维的推导,可以对代码等价变形得到一维的
第二问可以初始dp[0]合法,转移时只能从合法状态转移过来
可以手推一下