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
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]);
  }
  int sum=0;
  for(i=0;i<n;i++)
  {
   sum+=abs(a[i]-b[i]);
  }
  for(i=0;i<n-1;i++)
   sum+=abs(b[i]-b[i+1]);
  printf("%d\n",sum);
 }
 return 0;
}
原创粉丝点击