poj2313 Sequence ***

/*
* 贪心:
* 但自己没想出来, 看了网上的解法。。似乎也不太懂。 。 网上给的解法倒是可以证明是对的,但不知道是怎么想的
* 先给网上的解法:
* //开始假设b[i] = a[i](1 <= i <= n)
* //显然b[i]对于最后最优值产生影响的有三项|a[i]-b[i]|,|b[i]-b[i-1]|,|b[i]-b[i+1]|
* //反应在数轴上要使得这三项最小,那么取值应该是这三数居中的那个
* //若存在i使 b[i] < 或者 > Mid(b[i - 1], a[i], b[i + 1]) (2 <= i <= n - 1)
* //{mid(x, y, z)表示x, y, z中数值居中间的数}这个画下数轴就知道了
* //则b[i]=mid(b[i - 1], a[i], b[i + 1])
* //直到没有以上所说的i
* //所得的b数列即为所求
* //按公式求sum
* //输出
*
* 证明: 可以用数学归纳法。。这里认为初始时 b[i] = a[i]
* n = 3: 很显然,b[0]=a[0]..b[2]=a[2]..b[1]=mid(b[0], a[1], b[2])时表达式有最小值 = |a[2]-a[0]|
* 先看 n = 4.. 如果我们令b[2] = mid(b[1], a[2], b[3]),
* 那么可以保证: b[1]仍是mid(b[0], a[1], b[2])。(这个枚举一下就出来了)
* 所以前面的值仍是最小。。 然后令b[2] = mid(b[1], a[2], b[3])..
* 这时,可以保证 |b[2]-a[2]|+|b[2]-b[3]|+|b[3]-a[3]|最小 =|a[2]-a[3]|
* 所以表达式的前面一部分最小(因为b[1]=mid(b[0], a[1], b[2]))且后面一部分最小(因为b[2] = mid(b[1], a[2], b[3]))
* ,自然其值也是最小
* 所以对于 n = 4 的情况也是满足的
*
* 至于n = 5 。。。 也是满足的。。
*
*
*
*/

#include
<cstdio>
#include
<cmath>
using namespace std;

const int maxN = 100 + 5;
int a[maxN], b[maxN], n;

//取中位数
int getMid(int a, int b, int c){
int min = a, max = a;
min
= (min < b ? min : b);
min
= (min < c ? min : c);
max
= (max > b ? max : b);
max
= (max > c ? max : c);
return a + b + c - min - max;
}

int main(){
scanf(
"%d", &n);
for(int i=0; i<n; i++){
scanf(
"%d", &a[i]);
b[i]
= a[i];
}

for(int i=1; i<n-1; i++)
b[i]
= getMid(b[i-1], a[i], b[i+1]);

int ans = 0;
for(int i=0; i<n; i++)
ans
+= abs(a[i] - b[i]);
for(int i=0; i<n-1; i++)
ans
+= abs(b[i] - b[i+1]);

printf(
"%d\n", ans);


return 0;
}
原文地址:https://www.cnblogs.com/longdouhzt/p/2122156.html