背包 求最大获得价值
更新的时候用二维数组记录更新的状态,最后由最大值往回推,就是选择的顺序了
#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
#include<stack>
using namespace std;
const int maxn = 100 + 7;
int n, max_;
int ans[20*maxn];
int path[maxn][20*maxn];
struct node {
int t, d, v, id;
}a[maxn];
bool cmp(node a, node b) {
//if(a.d == b.d) return a.v > b.v;
return a.d < b.d;
}
void init() {
cin >> n;
for(int i = 0; i < n; ++i) {
//scanf("%d %d %d", &a[i].t, &a[i].d, &a[i].v);
cin >> a[i].t >> a[i].d >> a[i].v;
a[i].id = i + 1;
max_ = max(max_, a[i].d);
}
sort(a, a+n, cmp);
}
void solve() {
memset(ans, 0, sizeof ans);
memset(path, 0, sizeof path);
for(int i = 0; i < n; ++i) {
//cout << a[i].t << " = " << a[i].d << endl;
for(int j = a[i].d; j > a[i].t; --j) {
//if(j >= a[i].t && j <= a[i].d) {
if(ans[j-a[i].t]+a[i].v > ans[j]) {
ans[j] = ans[j-a[i].t]+a[i].v;
path[i][j] = 1;
//cout << j << " JJ " << ans[j] << endl;
//cout << i << " = " << j << " = " << a[i].v << endl;
}
//}
}
}
int maxx = 0, id = 0;
for(int j = 0; j <= max_; ++j)
if(ans[j] > maxx) { maxx = ans[j]; id = j; }
cout << maxx << endl;
stack<int> sk;
int cnt = 0;
int i = n-1, j = id;
while(i >= 0 && j >= 0) {
if(path[i][j] == 1) {
sk.push(a[i].id); cnt++;
j -= a[i].t;
}
i--;
}
cout << cnt << endl;
while(!sk.empty()) {
cout << sk.top(); sk.pop();
if(sk.empty()) cout << endl;
else cout << " ";
}
}
int main() {
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
ios::sync_with_stdio(0);
init();
solve();
return 0;
}