
想出来一个(目前)不知真伪的写法
从1到n遍历,遇到当前容量(j)下价值(w)更大的方案就把path[j]清空,把path[j-v]转移过来,加上i
遇到当前容量下价值相等的方案就比较path[j-v] + i和path[j]的字典序
题解是从n到1遍历,用二维数组f[i][j]存状态
最后从1到n遍历,判断当前点(i)是否能从i+1转移过来,能选则选
#include<bits/stdc++.h>
using namespace std;
#define fr first
#define se second
typedef pair<int, int> PII;
typedef long long LL;
typedef unsigned long long ULL;
const int INF = 0X3f3f3f3f, N = 1000 + 10, MOD = 1e9 + 7;
int n,m;
int f[N];
vector<int> path[N];
bool cmp(vector<int> &x,vector<int> &y){
for(int i=0;i<x.size() || i<y.size();i++){
if(i>=x.size()) return true;
if(i>=y.size()) return false;
if(x[i] < y[i]) return true;
if(x[i] > y[i]) return false;
}
}
void work() {
cin>>n>>m;
for(int i=1;i<=n;i++){
int v,w;
cin>>v>>w;
for(int j=m;j>=v;j--){
int u=f[j-v]+w;
if(u>f[j]){
f[j]=u;
path[j].clear();
path[j]=path[j-v];
path[j].push_back(i);
}
else if(u==f[j]){
vector<int> tmp = path[j-v];
tmp.push_back(i);
if(cmp(tmp,path[j])) path[j] = tmp;
}
}
}
// cout<<f[m]<<endl;
for(int i=0;i<path[m].size();i++) cout<<path[m][i]<<" ";
cout<<endl;
}
signed main() {
work();
return 0;
}