poj2313(贪心)
来源:互联网 发布:win10关闭软件快捷键 编辑:程序博客网 时间:2024/06/07 09:40
http://poj.org/problem?id=2313
Sequence
Time Limit: 1000MSMemory Limit: 65536KTotal Submissions: 3333Accepted: 1341
Description
Given a sequencewith N integers A(1), A(2), ..., A(N), your task is to find out asequence B(1), B(2), ..., B(N), such that
is minimum.
V = (|A(1) – B(1)| + |A(2) – B(2)| + ... + |A(N) – B(N)|) + (|B(1) – B(2)| + |B(2) – B(3)| + ... +|B(N-1) – B(N)|)
is minimum.
Input
The first line inthe input contains an integer N (1 <= N<= 100). Then follow N lines, the i-th of whichcontains an integer A(i) (-10000 <= A(i)<= 10000).
Output
The output onlycontains an integer, which is the minimum value of V.
Sample Input
3358
Sample Output
5
Source
POJ Monthly,Minkerui
题意:求
V = (|A(1) – B(1)| + |A(2) – B(2)| + ... + |A(N) – B(N)|) + (|B(1) – B(2)| + |B(2) – B(3)| + ... +|B(N-1) – B(N)|)的最小值。。其中A[i]是给定的。。B[i]是未知的(自己构造)这就是本题的关键地方。。。。
先给网上的证明法:
* //开始假设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<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
#define MAXN 110
int a[MAXN],b[MAXN];
int Mid(int i,int j,int k)//取中位数
{
int s[3];
s[0]=i;
s[1]=j;
s[2]=k;
sort(s,s+3);
return s[1];
}
//int Mid(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()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int i;
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
}
for(i=1;i<n-1;i++)
{
b[i]=Mid(b[i-1],a[i],b[i+1]);
}