先从后往前求背包问题 然后从前往后求具体方案
因为是求字典序最小的方案 那么 如果当前的物品能选就一定要选
#include<bits/stdc++.h> using namespace std; const int N = 1010; int n,m; int v[N],w[N]; int f[N][N]; int main(){ cin >> n >> m; for(int i = 1;i <= n;++i)cin >> v[i] >> w[i]; for(int i = n ;i >= 1;--i){ for(int j = 0;j <= m;++j){ f[i][j] = f[i + 1][j]; if(j >= v[i]) f[i][j] = max(f[i][j],f[i + 1][j - v[i]] + w[i]); } } int j = m; for(int i = 1;i <= n;++i){ //如果背包的容量还能放下 i 并且放与不放答案相同 那么就一定要选 if(j >= v[i] && f[i][j] == f[i + 1][j - v[i]] + w[i]){ cout << i << " " ; j -= v[i]; } } return 0; }