题目描述
Description
LichKing 希望收集邪恶的黑暗力量,并依靠它称霸世界。
世间的黑暗力量被描述成一个长度为N 的非负整数序列{Ai},每次它可以选择这个序列中的两个相邻的正整数,让他们的值同时减一并获得一点邪恶力量,直到不存在满足条件的数。
然而你不希望他能够得逞,所以你会使得他收集的能量尽可能少。
Input
N
A1 A2 … AN
Output
输出一行一个整数,表示答案。
Sample Input
10
2 0 1 2 0 0 0 0 0 0
Sample Output
1
Data Constraint
思路
这题可以考虑用dp来做。
设 f i f_i fi表示 i i i这个位置要取完且 1 1 1~ i i i都合法。
因为是两个连续的数,所以可以考虑从三个位置转移。
1. f i − 1 f_{i-1} fi−1转移。由于要将连续两个取完,即 f i = f i − 1 + a i f_i=f_{i-1}+a_i fi=fi−1+ai。
2. f i − 2 f_{i-2} fi−2转移。表示空一个取,即 f i = f i − 2 + a i f_i=f_{i-2}+a_i fi=fi−2+ai。
3. f i − 3 f_{i-3} fi−3转移。表示空两个取,即 f i = f i − 3 + m a x ( a i − 1 , a i ) f_i=f_{i-3}+max(a_{i-1},a_i) fi=fi−3+max(ai−1,ai)。因为必须i和i-1都取完,才能够保证i-2和i-1不连着。
将上述转移式整合一下,就可得
f i = m i n ( m i n ( f i − 1 + a i , f i − 2 + a i ) , f i − 3 + m a x ( a i − 1 , a i ) ) f_i=min(min(f_{i-1}+a_i,f_{i-2}+a_i),f_{i-3}+max(a_{i-1},a_i)) fi=min(min(fi−1+ai,fi−2+ai),fi−3+max(ai−1,ai))
但你会发现一些interesting的问题
如:
……4 3 6 2……,当运行到6时,你会发现不可能取6个,最多只能取5个,那会不会影响答案呢?
并不会,因为错误的计算算出来的答案会多,自然会比正确情况的答案多,而正解又包含在我们推导的三个情况里,所以正解会筛掉错误的计算。
Code
#include<cstdio>
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
int n,a[100005],f[100005];
int main()
{
fre(dark);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
f[1]=a[1],f[2]=a[2];
for(int i=3;i<=n;i++)
f[i]=min(min(f[i-1]+a[i],f[i-2]+a[i]),f[i-3]+max(a[i],a[i-1]));
printf("%d",min(f[n-1],f[n]));
}