CF864 E DP 输出路径

n个物品有Deadline,拿物品需要花费时间,问取得最大价值的方案。

本质是个01背包,先按时间排序,然后把花费的时间作为背包就行了。

主要就是找方案,倒过来找发生转移的就行了。

太菜了真的不会打CF,每次都要掉分

/** @Date    : 2017-09-25 22:28:30
  * @FileName: E.cpp
  * @Platform: Windows
  * @Author  : Lweleth ([email protected])
  * @Link    : https://github.com/
  * @Version : $Id$
  */
#include <bits/stdc++.h>
#define LL long long
#define PII pair<int ,int>
#define MP(x, y) make_pair((x),(y))
#define fi first
#define se second
#define PB(x) push_back((x))
#define MMG(x) memset((x), -1,sizeof(x))
#define MMF(x) memset((x),0,sizeof(x))
#define MMI(x) memset((x), INF, sizeof(x))
using namespace std;

const int INF = 0x3f3f3f3f;
const int N = 2e5+20;
const double eps = 1e-8;

int n;
int dp[110][3000];
struct yuu
{
	int v, c, d, idx;
}a[200];

int cmp(yuu a, yuu b)
{
	if(a.d != b.d)
		return a.d < b.d;
	return a.c < b.c;
}
int main()
{
	cin >> n;
	int sum = 0;
	for(int i = 1; i <= n; i++)
	{
		scanf("%d%d%d", &a[i].c, &a[i].d, &a[i].v), a[i].idx = i;
		sum += a[i].c;
	}
	sort(a + 1, a + n + 1, cmp);
	MMF(dp);
	int ma = 0;
	int pos = 0;
	for(int i = 1; i <= n; i++)
	{
		for(int j = 0; j <= sum; j++)
		{
			if(j < a[i].d && j >= a[i].c)
				dp[i][j] = max(dp[i - 1][j - a[i].c] + a[i].v, dp[i - 1][j]);
			else dp[i][j] = dp[i - 1][j];
			if(ma < dp[i][j])
				pos = j, ma = dp[i][j];
		}
	}
	vector<int>q;
	for(int i = n; i >= 1; i--)
	{
		if(pos > a[i].d || pos < a[i].c || dp[i - 1][pos] >= dp[i - 1][pos - a[i].c] + a[i].v)
			continue;
		pos -= a[i].c;
		q.PB(i);
	}
	reverse(q.begin(), q.end());
	printf("%d\n", ma);
	printf("%d\n", q.size());
	for(auto i : q)
		printf("%d ", a[i].idx);
	printf("\n");
    return 0;
}
时间: 2024-11-05 11:24:53

CF864 E DP 输出路径的相关文章

uva 11578 - Situp Benches(dp+输出路径)

题目连接:uva 11578 - Situp Benches 题目大意:健身房有两个仪器,初始角度为10度,每次有人使用需要交15元,每调10度需要花费10元,现在有n个人,给出每个人使用仪器的顺序和角度,保证不会同时有大于2个人序号一样,求最小花费,并且输出每个人分别使用哪一个仪器,并且所有人使用结束后,要将仪器调回10度. 解题思路:dp[i][x][y]表示第i个人,一个仪器为x,另一个仪器为y的情况,path[i][x][y]记录的是它的前一个状态,[0]为前一个仪器的夹角,[1]为另一

FatMouse&#39;s Speed--hdu1160(dp+输出路径)

Problem Description FatMouse believes that the fatter a mouse is, the faster it runs. To disprove this, you want to take the data on a collection of mice and put as large a subset of this data as possible into a sequence so that the weights are incre

URAL 1900. Brainwashing Device(dp+输出路径)

1900. Brainwashing Device Time limit: 1.0 second Memory limit: 64 MB While some people travel in space from planet to planet and discover new worlds, the others who live on Earth still have to get up in the morning, go to work, return back home and t

hdoj 5092 Seam Carving 【树塔DP变形 + 路径输出】 【简单题】

Seam Carving Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 956    Accepted Submission(s): 382 Problem Description Fish likes to take photo with his friends. Several days ago, he found that so

poj 2250 Compromise dp lcs 路径输出

点击打开链接题目链接 Compromise Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6520   Accepted: 2922   Special Judge Description In a few months the European Currency Union will become a reality. However, to join the club, the Maastricht criteria

51nod_1006 最长公共子序列,输出路径【DP】

题意: 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列. 输出最长的子序列,如果有多个,随意输出1个. 思路: DP,同时DP记录路径. 代码: string a,b; int f[1005][1005]; int path[1005][1005]; void _print(int x,int y){ if(!x||!y) ret;

hdu 1160 FatMouse&#39;s Speed(最长不下降子序列+输出路径)

题意: FatMouse believes that the fatter a mouse is, the faster it runs. To disprove this, you want to take the data on a collection of mice and put as large a subset of this data as possible into a sequence so that the weights are increasing, but the s

CD-----UVa624(01背包+输出路径)

  CD  You have a long drive by car ahead. You have a tape recorder, but unfortunately your best music is on CDs. You need to have it on tapes so the problem to solve is: you have a tape N minutes long. How to choose tracks from CD to get most out of

POJ 1141 Brackets Sequence (区间dp 记录路径)

题目大意: 给出一种不合法的括号序列,要求构造出一种合法的序列,使得填充的括号最少. 思路分析: 如果只要求输出最少的匹配括号的数量,那么就是简单的区间dp dp[i][j]表示 i - j 之间已经合法了最少添加的括号数. 转移 就是 dp[i] [j] = min  (dp[i+1][j]+1 , dp[ i+ 1] [ k -1 ] + dp[k+1] [j] (i k 位置的括号匹配)) 其次我们要记录路径,你发现  如果 dp [i] [j] 是由 dp [i+1] [j] 转移过来的