题目:https://codeforces.com/gym/100819/attachments
这个题目和尼克的任务这个题目很像,这个题目因为同一时刻具有选择性,而且每一次的选择会对后面的选择产生影响,所以从正面往后推不太方便。
正难则反,所以把时间从后往前推,这样的话,因为后面的决策已经有了,所以前面不会对后面产生影响,就没有后效性。
大概就是这个意思把,我也不是很确定。。。。
我觉得要注意三个地方,一个是用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 ", ans); return 0; }