要求字典序最小,每次都要问第i件物品选不选,如果选,就是选;如果不选,就从i+1(之后一个)转移过来,这是一个。。。
可是为什么要从大到小遍历呢?
// f[i][j]表示第i件物品以后选,体积不超过j的价值最大值
// 所以要从n开始倒着
// 才能求最小方案时正着推
// f[i][j]=max(f[i+1][j],f[i+1][j-v[i]+w[i])
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
int f[N][N];
int v[N],w[N];
int n,V;
int main()
{
cin>>n>>V;
for(int i=1;i<=n;i++) cin>>v[i]>>w[i];
for(int i=n;i>=1;i--)
{
for(int j=0;j<=V;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 cur_v=V;
for(int i=1;i<=n;i++) //从第一个物品
{
if(cur_v>=v[i] && f[i+1][cur_v-v[i]]+w[i]>=f[i+1][cur_v])
{
printf("%d ",i);
cur_v-=v[i];
}
}
}