Codeforces Round #436 (Div. 2) E. Fire (有放入顺序有关的01背包)
来源:互联网 发布:马克斯cms手机站 编辑:程序博客网 时间:2024/05/19 04:52
Polycarp is in really serious trouble — his house is on fire! It's time to save the most valuable items. Polycarp estimated that it would take tiseconds to save i-th item. In addition, for each item, he estimated the value of di — the moment after which the item i will be completely burned and will no longer be valuable for him at all. In particular, if ti ≥ di, then i-th item cannot be saved.
Given the values pi for each of the items, find a set of items that Polycarp can save such that the total value of this items is maximum possible. Polycarp saves the items one after another. For example, if he takes item a first, and then item b, then the item a will be saved in ta seconds, and the item b — in ta + tb seconds after fire started.
The first line contains a single integer n (1 ≤ n ≤ 100) — the number of items in Polycarp's house.
Each of the following n lines contains three integers ti, di, pi (1 ≤ ti ≤ 20, 1 ≤ di ≤ 2 000, 1 ≤ pi ≤ 20) — the time needed to save the item i, the time after which the item i will burn completely and the value of item i.
In the first line print the maximum possible total value of the set of saved items. In the second line print one integer m — the number of items in the desired set. In the third line print m distinct integers — numbers of the saved items in the order Polycarp saves them. Items are 1-indexed in the same order in which they appear in the input. If there are several answers, print any of them.
33 7 42 6 53 7 6
1122 3
25 6 13 3 5
111
In the first example Polycarp will have time to save any two items, but in order to maximize the total value of the saved items, he must save the second and the third item. For example, he can firstly save the third item in 3 seconds, and then save the second item in another 2seconds. Thus, the total value of the saved items will be 6 + 5 = 11.
In the second example Polycarp can save only the first item, since even if he immediately starts saving the second item, he can save it in 3seconds, but this item will already be completely burned by this time.
#include <stdio.h>#include <string.h>#include <bits/stdc++.h>using namespace std;struct node{int t, d, p, id;bool operator < (const node& x){return d < x.d;}}a[101];int dp[101][2001], pre[101][2001];int main(){int n;scanf("%d", &n);for(int i = 1; i <= n; ++i){scanf("%d %d %d", &a[i].t, &a[i].d, &a[i].p);a[i].id = i;}sort(a + 1, a + 1 + n);memset(dp, 0, sizeof(dp));for(int i = 1; i <= n; ++i){for(int j = 0; j <= n * 20; ++j){dp[i][j] = dp[i - 1][j];pre[i][j] = j;if(j >= a[i].t && j < a[i].d){if(dp[i][j] < dp[i - 1][j - a[i].t] + a[i].p){dp[i][j] = dp[i - 1][j - a[i].t] + a[i].p;pre[i][j] = j - a[i].t;}}}}int tot = 0;for(int i = 0; i <= n * 20; ++i){if(dp[n][i] > dp[n][tot]){tot = i;}}printf("%d\n", dp[n][tot]);vector<int> ans;for(int i = n; i >= 1; --i){if(pre[i][tot] != tot){ans.push_back(a[i].id);tot = pre[i][tot];}}printf("%d\n", ans.size());for(int i = ans.size() - 1; i >= 0; --i){printf("%d ", ans[i]);}}/*题意:有个房子着火了,里面有100个物品,现在要把这些东西拿出来,每个物品有一个价值,拿出来所需的时间,和能承受火的最长时间,问最多可以拿出多少价值的物品。思路:这题其实就是01背包,但是和放入背包的顺序很明显是有关的,一般这种问题都可以先思考这样一个问题,假如对于某一种解,解中所有物品我都可以拿出来,需要按照什么顺序放入背包才可以保证解成立。对于这一题来说,假如相邻两个放入背包的是i,j,那么对于前面物品的放入顺序和后面的放入顺序,对于这两个物品是没有影响的,因为当前后解成立时,影响因素只有t的求和,很显然前面的t求和是固定,加上i,j后求和也是固定的(即前面的放入顺序对后面无影响),所以无论前后按什么顺序来放,只要解正确,那么就对i,j没有影响,现在我们单独考虑i,j。根据题目的要求显然ti + tj < max(di, dj),就是如果两个全部拿出来总共用的时间不能超过其中某个最大承受火时间的物品的d,这个在假设中保证的。如果先拿i,即ti + tj < di,如果先拿j,即tj + ti < dj,根据要求,如果两个都能拿,我们应该把d大的放在后面。虽然这个顺序在某种情况下可能是不影响解的成立的,但是只有按顺序拿时才可以保证无法构造出一个反例去让解无法成立。*/
- Codeforces Round #436 (Div. 2) E. Fire (有放入顺序有关的01背包)
- Codeforces Round #436 (Div. 2)-E-Fire(01背包输出路径)
- Codeforces Round #436 (Div. 2) E. Fire(01背包+输出路径)
- 【01背包 && 记录路径 && 约束】Codeforces Round #436 (Div. 2) E. Fire
- Codeforces 864E (Codeforces Round #436 (Div. 2)) E. Fire 背包输出路径
- Codeforces Round #436 (Div. 2) E. Fire
- Codeforces Round #436 (Div. 2)E.Fire
- Codeforces Round #436 (Div. 2)E. Fire
- Codeforces Round #436 (Div. 2) E. Fire
- Codeforces Round #436 (Div. 2) E. Fire(背包DP+输出路径)
- Codeforces Round #436 (Div. 2)-背包&排序&输出状态-E. Fire
- Codeforces Round #436 E.Fire(01背包 + 输出路径)
- Codeforces Round #436 (Div. 2) E fire DP
- Codeforces Round #436 (Div. 2) 864E. Fire
- Codeforces Round #105 (Div. 2)--E. Porcelain 01背包
- Codeforces Round #360 (Div. 2) E dp 类似01背包
- Codeforces Round #105 (Div. 2) E 01背包
- Codeforces Round #436 E. Fire
- 高考日 vivo携宋仲基#助力梦想 vivo同行#为考生服务
- 浙江高考作文题是VR,这是我的回答
- Java 打印质数 goto思想应用
- 简单的数论小知识
- python数据类型--列表
- Codeforces Round #436 (Div. 2) E. Fire (有放入顺序有关的01背包)
- 多线程-线程同步问题
- python笔记
- java8之lambda表达式
- 基于TextRank的关键词、短语、摘要提取
- LeetCode刷题(24)
- CSS基础笔记
- 国外十大高校人工智能实验室及其代表性人物一览
- 1--springBoot的注解使用,aspectj注解的使用,配置类的使用