码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 864E Fire(DP)

时间:2017-09-26 01:10:42      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:oid   break   ble   cpp   target   putc   printf   def   efi   

题目链接 Fire

题意 有n个物品,每个物品的挽救时间代价为ti, 消失时刻为di, 价值为pi。

如果要救某个物品,必须在他消失之前救出来。

同一时刻最多只能救一件物品。

当前耗时为当前已经救出的物品的ti累积。

你需要救出总价值尽可能大的物品,并输出方案。

 

考虑DP

f[i][j]为考虑前i个物品,获得总价值为j的时候,所用时间的最小值。

c[i][j]为在搜索到第i件物品,当前总价值为j的时候下一步的价值搜索状态。

则有f[i][j] = f[i - 1][j - a[i].p] + a[i].t

取最大值的时候考虑最大的i满足f[n][i] != INF即可。

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b)	for (int i(a); i >= (b); --i)

const int N = 105;
const int Q = 2010;

struct node{
	int t, d, p;
	int id;
	friend bool operator < (const node &a, const node &b){
		return a.d < b.d;
	}
} a[N];

int f[N][Q], c[N][Q];
int n, cnt = 0;
int ans[N];

void solve(int i, int j){
	if (i == 0) return;
	if (c[i][j] != j) ans[++cnt] = a[i].id;
	solve(i - 1, c[i][j]);
}

int main(){
        
	scanf("%d", &n);
	rep(i, 1, n){
		scanf("%d%d%d", &a[i].t, &a[i].d, &a[i].p);
		a[i].id = i;
	}

	sort(a + 1, a + n + 1);

	rep(i, 0, n) rep(j, 0, 2001) f[i][j] = 1 << 30;
	f[0][0] = 0;
	rep(i, 1, n){
		rep(j, 0, 2000){
			f[i][j] = f[i - 1][j];
			c[i][j] = j;
			if (j < a[i].p) continue;
			int now = f[i - 1][j - a[i].p] + a[i].t;
			if (now < f[i][j] && now < a[i].d){
				f[i][j] = now;
		 		c[i][j] = j - a[i].p;
			}
		}
	}

	dec(i, 2000, 0) if (f[n][i] < (1 << 30)){
		printf("%d\n", i);
		solve(n, i);
		printf("%d\n", cnt);
		dec(j, cnt, 1) printf("%d ", ans[j]);
		putchar(10);
		break;
	}

	return 0;
}

 

Codeforces 864E Fire(DP)

标签:oid   break   ble   cpp   target   putc   printf   def   efi   

原文地址:http://www.cnblogs.com/cxhscst2/p/7594639.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!