宵暗的妖怪(dp)
前言:越到考试周越浪,最近写了一些思维题,也没空总结(毕竟一堆ddl,并且这周上完课下周就考试),不过这道dp有点意思,就摘了下来,发现听着听着毛概课咋莫名奇妙一些题就有灵感了,这就很离谱。
题目:
露米娅作为宵暗的妖怪,非常喜欢吞噬黑暗。
这天,她来到了一条路上,准备吞噬这条路上的黑暗。
这条道路一共被分为n部分,每个部分上的黑暗数量为ai。
露米娅每次可以任取 连续的 未被吞噬过的 三部分,将其中的黑暗全部吞噬,并获得中间部分的饱食度。
露米娅想知道,自己能获得的饱食度最大值是多少?
输入描述:
第一行一个正整数n,代表道路被分的份数。
第二行有n个正整数ai,代表每一部分黑暗数量。
数据范围:3 <= n <= 100000, 1 <= ai <= 10^9
输出描述:
一个正整数,代表最终饱食度的最大值。
示例1
输入
7
2 4 1 4 2 1 8
输出
6
说明
选择[2,4,1]和[4,2,1]这两段即可。饱食度为4+2=6。
示例2
输入
7
2 4 1 7 2 1 8
输出
7
说明
选择[1,7,2]这一段即可。饱食度为7。
值得注意的是,若取两段进行吞噬,反而最多只能获得6的饱食度,并不是最大的。
解析:设dp[i]为前i个数能获得最大的饱食度,其实就分两种情况,要么取第i个数作为中间数,要么不取。
取第i个数作为中间数:dp[i] = dp[i-3] + a[i]; 假如取了第i个数,那和它相连的上一个只能是它的前三个数(i-3),因为每取一个数,它左右两边的数相当于会消失相当于(i-1)与(i+1)无效了,若取i-2说明i-1必须要有效,所以只能是(i-3)。
不取第i个数dp[i] = dp[i-1];
此时前i个数获得的饱食度肯定就是和前i-1个数获得的饱食度一样。
然后比较一下这两者的大小,取个max即可。
ps: 注意一下数组别越界了,当i=2的时候会翻车的。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e5 + 7;
LL a[N], n, dp[N];
int main()
{
ios::sync_with_stdio(false);
// freopen("cin.in", "r", stdin);
// freopen("cout.out", "w", stdout);
memset(dp, 0, sizeof(dp));
cin >> n;
for(int i = 1; i <= n; i++)
cin >> a[i];
dp[2] = a[2];
for(int i = 3; i < n; i++)
dp[i] = max(dp[i-3] + a[i], dp[i-1]); //dp[i]: 前i个元素达到的最大饱食度
cout << dp[n-1] << endl;
return 0;
}

浙公网安备 33010602011771号