[luoguP1156] 垃圾陷阱(DP)

传送门

先按照时间排序

f[i][j] 表示 前i个物品高度为j时所剩余的最大能量

显然每个物品有堆和吃两种选择

状态转移看代码

代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 1001
#define max(x, y) ((x) > (y) ? (x) : (y))

int d, g, ans;
int f[N][N];

struct node
{
	int t, x, y;
}p[N];

inline int read()
{
	int x = 0, f = 1;
	char ch = getchar();
	for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
	for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
	return x * f;
}

inline bool cmp(node x, node y)
{
	return x.t < y.t;
}

int main()
{
	int i, j;
	d = read();
	g = read();
	for(i = 1; i <= g; i++)
	{
		p[i].t = read();
		p[i].x = read();
		p[i].y = read();
	}
	std::sort(p + 1, p + g + 1, cmp);
	memset(f, -1, sizeof(f));
	f[0][0] = 10;
	for(i = 1; i <= g; i++)
		for(j = 0; j <= d; j++)
		{
			if(f[i - 1][j] >= p[i].t - p[i - 1].t) f[i][j] = max(f[i][j], f[i - 1][j] + p[i].x - (p[i].t - p[i - 1].t));
			if(f[i - 1][j - p[i].y] >= p[i].t - p[i - 1].t && j >= p[i].y)
			{
				f[i][j] = max(f[i][j], f[i - 1][j - p[i].y] - (p[i].t - p[i - 1].t));
				if(j == d)
				{
					printf("%d
", p[i].t);
					return 0;
				}
			}
		}
	for(i = 1; i <= g; i++)
		for(j = 0; j <= d; j++)
			if(f[i][j] ^ -1)
				ans = max(ans, f[i][j] + p[i].t);
	printf("%d
", ans);
	return 0;
}

  

原文地址:https://www.cnblogs.com/zhenghaotian/p/7063760.html