dp Surf

题目:https://vj.69fa.cn/1fc993e7e0e1e6fa7ce4640b8d46ef8d?v=1552762626

这个题目和尼克的任务这个题目很像,这个题目因为同一时刻具有选择性,而且每一次的选择会对后面的选择产生影响,所以从正面往后推不太方便。

正难则反,所以把时间从后往前推,这样的话,因为后面的决策已经有了,所以前面不会对后面产生影响,就没有后效性。

大概就是这个意思把,我也不是很确定。。。。

我觉得要注意三个地方,一个是用long long,应该是要的,还有就是dp每次转移不能只向前面一个转移,而应该向前面两个中较大的一个转移,还有就是数组要开2e6,不然就越界了。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
#include <iostream>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 2e6 + 100;
const int mx = 3e5 + 100;
ll dp[maxn];
int vis[maxn];
struct node
{
	int ac, happy, con;
}exa[mx];

bool cmp(const node& a, const node& b)
{
	return a.ac > b.ac;
}

int main()
{
	int n, num = 1;
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		scanf("%d%d%d", &exa[i].ac, &exa[i].happy, &exa[i].con);
		vis[exa[i].ac]++;
	}
	sort(exa + 1, exa + n + 1, cmp);
	int len = exa[1].ac;
	ll ans = -inf;
	for (int i = len; i >= 0; i--)
	{
		if (!vis[i]) dp[i] = max(dp[i + 1], dp[i + 2]);
		else
		{
			dp[i] = max(dp[i + 1], dp[i + 2]);
			for (int j = 1; j <= vis[i]; j++)
			{
				if (dp[i + exa[num].con] + exa[num].happy > dp[i])
					dp[i] = dp[i + exa[num].con] + exa[num].happy;
				num++;
			}
		}
		ans = max(ans, dp[i]);
	}
	printf("%lld\n", ans);
	return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/EchoZQN/p/10555428.html
今日推荐