zoukankan      html  css  js  c++  java
  • bzoj1592 Making the Grade

    Description

    FJ打算好好修一下农场中某条凹凸不平的土路。按奶牛们的要求,修好后的路面高度应当单调上升或单调下降,也就是说,高度上升与高度下降的路段不能同时出现在修好的路中。 整条路被分成了N段,N个整数A_1, ... , A_N (1 <= N <= 2,000)依次描述了每一段路的高度(0 <= A_i <= 1,000,000,000)。FJ希望找到一个恰好含N个元素的不上升或不下降序列B_1, ... , B_N,作为修过的路中每个路段的高度。由于将每一段路垫高或挖低一个单位的花费相同,修路的总支出可以表示为: |A_1 - B_1| + |A_2 - B_2| + ... + |A_N - B_N| 请你计算一下,FJ在这项工程上的最小支出是多少。FJ向你保证,这个支出不会超过2^31-1。

    Input

    * 第1行: 输入1个整数:N * 第2..N+1行: 第i+1行为1个整数:A_i

    Output

    * 第1行: 输出1个正整数,表示FJ把路修成高度不上升或高度不下降的最小花费

    Sample Input

    7
    1
    3
    2
    4
    5
    3
    9

    Sample Output

    3

    HINT

    FJ将第一个高度为3的路段的高度减少为2,将第二个高度为3的路段的高度增加到5,总花费为|2-3|+|5-3| = 3,并且各路段的高度为一个不下降序列 1,2,2,4,5,5,9。

    solution

    首先得离散一下.........

    之后证明修改之后的值一定是原来值中的一个:

    假设a[i] 修改之后 为k,如果k==a[i] 则说明k为原来中的一个

    如果k!=a[i],说明它经过了上下挪,当它挪到与前一个相等时,就不必再挪,所以k==a[i]

    然后就是dp   f[i][j] i为当前到了哪一位 j为第i位选择的高度

    f[i][j]=min(f[i][j-1],f[i-1][k]+abs(h[j]-a[i]))  k<=j

    时间复杂度 O(n^2)

    一个变量就可以维护f[i-1][k]最小值  (old driver提出)

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 #define mem(a,b) memset(a,b,sizeof(a))
     6 using namespace std;
     7 const int N=2006;
     8 inline int minn(int a,int b){return a<b?a:b;}
     9 inline int abss(int x){return x<0?-x:x;}
    10 struct son1
    11 {
    12     int pos,val;
    13     friend bool operator < (const son1 &a,const son1 &b)
    14     {
    15         return a.val<b.val;
    16     }
    17 };
    18 son1 ji[N];
    19 
    20 int n,cnt;
    21 int a[N];
    22 int ha[N];
    23 int minl1,minl2,ans;
    24 int f[2066][2066];
    25 
    26 int main(){
    27     //freopen("grading.2.in","r",stdin);
    28     scanf("%d",&n);
    29     for(int i=1;i<=n;++i)
    30     {
    31       scanf("%d",&ji[i].val);
    32       ji[i].pos=i;
    33     }
    34     sort(ji+1,ji+1+n);
    35     ji[0].val=-100;
    36     for(int i=1;i<=n;++i)
    37     {
    38         if(ji[i].val!=ji[i-1].val)
    39           ha[++cnt]=ji[i].val;
    40         a[ji[i].pos]=cnt;
    41     }
    42     
    43     for(int i=1;i<=n;++i)
    44     {
    45         f[i][0]=0x7fffffff;
    46         int minl=0x7fffffff;
    47         for(int j=1;j<=cnt;++j)
    48         {
    49             minl=minn(minl,f[i-1][j]);
    50             f[i][j]=minn(f[i][j-1],minl+abss(ha[j]-ha[a[i]]));
    51         }
    52     }
    53     
    54     minl1=f[n][cnt];
    55     
    56     mem(f,0);
    57     for(int i=1;i<=n;++i)
    58     {
    59         f[i][cnt+1]=0x7fffffff;
    60         int minl=0x7fffffff;
    61         for(int j=cnt;j>=1;--j)
    62         {
    63             minl=minn(minl,f[i-1][j]);
    64             f[i][j]=minn(f[i][j+1],minl+abss(ha[j]-ha[a[i]]));
    65         }
    66     }
    67     
    68     minl2=f[n][1];
    69     
    70     printf("%d",minn(minl1,minl2));
    71     //while(1);
    72     return 0;
    73 }
    code
  • 相关阅读:
    wireshark安装
    高效使用搜索引擎
    MFC 网络编程 -- 总结
    MFC Grid control 2.27
    A Popup Progress Window
    Showing progress bar in a status bar pane
    Progress Control with Text
    Report List Controls
    第三方
    CBarChart柱形图类
  • 原文地址:https://www.cnblogs.com/A-LEAF/p/7275208.html
Copyright © 2011-2022 走看看