算法提高之背包问题背包问题求具体方案
-
核心思想:01背包 + dp输出方案
-
因为求字典序最小的方案 所以当取第i个物品时 下一步要求的就是i+1 ~ n的最大方案
-
所以f意义改变 变成了第i个元素到最后一个元素总容量为j的最优解
- 之前是前i个物品总容量为j的最优解
-
这样在之后递归从1~n找方案时 遇到分叉路径会优先取 而不是不取
-
-
#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 1010; int f[N][N]; int v[N],w[N],path[N]; int n,m,cnt; int main() { cin>>n>>m; for(int i=1;i<=n;i++) cin>>v[i]>>w[i]; for(int i=n;i;i--) { for(int j=0;j<=m;j++) { f[i][j] = f[i+1][j]; //都是i-1改成i+1 if(j>=v[i]) f[i][j] = max(f[i][j],f[i+1][j-v[i]] + w[i]); } } for(int i=1,j=m;i<=n;i++) { if(j>=v[i] && f[i][j] == f[i+1][j-v[i]] + w[i]) //都是i-1改成i+1 { path[cnt++] = i; j -= v[i]; } } for(int i=0;i<cnt;i++) { cout<<path[i]<<" "; } }