题意: 共30个题, 每个题有花费的时间(1e5), 价值(1e9), 最早可提交时间(1e5), 问最早在什么时间做题总价值达到W(1e9).
思路:
选择先做哪个题会影响到下一个题的开始时间.
先做允许提交时间最早的题不是最优的.
应当先尝试做 最早提交时间 最早的 题.
先按上面的要求对题目排序, 再01背包.
背包时注意当前时间要晚于允许提交时间.
参考:https://blog.csdn.net/stay_accept/article/details/51426214
代码:
#include<bits/stdc++.h>
using namespace std;
void debug_out() {
cerr << '\n';
}
template<typename T, typename ...R>
void debug_out(const T &f, const R &...r) {
cerr << f << " ";
debug_out(r...);
}
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]: ", debug_out(__VA_ARGS__);
typedef long long ll;
const int M = 1e5 + 5;
const int inf = 1e9 + 5;
const int mod = 1e9 + 7;
struct node {
int time, l;
ll w;
} item[35];
int n;
ll W;
ll sumw;
int maxt = M * 35;
ll dp[M * 35 + 5];
bool cmp(node a,node b){
return a.l-a.time<b.l-b.time;
}
int init() {
sumw = 0;
maxt=0;
int sumt=0;
memset(dp, 0, sizeof(dp));
for (int i = 0; i < n; i++) {
scanf("%d%I64d%d", &item[i].time, &item[i].w, &item[i].l);
sumw += item[i].w;
sumt+=item[i].time;
maxt=max(maxt,item[i].l);
}
maxt+=sumt;
if (sumw < W) {
printf("zhx is naive!\n");
return -1;
}
sort(item,item+n,cmp);
}
void solve() {
for (int i = 0; i < n; i++) {
for (int j = maxt; j >= 0; j--) {
if (j >= item[i].time && j>= item[i].l) {
dp[j] = max(dp[j], dp[j - item[i].time] + item[i].w);
}
// if(j<14)debug(i,j,dp[j]);
}
}
for (int i = 0; i <= maxt; i++) {
if (dp[i] >= W) {
printf("%d\n", i);
break;
}
}
}
int main() {
while (~scanf("%d%I64d", &n, &W)) {
if (init() == -1)continue;
solve();
}
return 0;
}