• [USACO08FEB]修路Making the Grade


    [USACO08FEB]修路Making the Grade
    比较难的dp,比赛时打的找LIS,然后其他的尽可能靠近,40分。
    先举个例子
    6
    1 2 3 1 4 5
    6
    1 2 3 3 4 5
    第4个1要么改成3,要么改成4,反正是数列中的数。
    所以最优情况下,答案中的数都是原数列中有的。
    b[]是a[]由小到大排序之后的数组
    令f[i][j]表示使前i个数成为不减的最小花费,而且第i个的高度为b[j].
    f[i][j]=min(f[i-1][k])+abs(a[i]-b[j]);1<=k<=n
    k从1~n递增,一个显然的优化就是单调队列,递增的,每次取队首。
    不增同理。

    AC:

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #include<cmath>
    #include<ctime>
    #include<cstring>
    #define inf 2147483647
    #define For(i,a,b) for(register int i=a;i<=b;i++)
    #define p(a) putchar(a)
    #define g() getchar()
    //by war
    //2017.10.18
    using namespace std;
    int f[2010][2010];
    int q[2010];
    int a[2010];
    int b[2010];
    int l,r;
    int ans;
    int n;
    int m;
    void in(int &x)
    {
        int y=1;
        char c=g();x=0;
        while(c<'0'||c>'9')
        {
        if(c=='-')
        y=-1;
        c=g();
        }
        while(c<='9'&&c>='0')x=x*10+c-'0',c=g();
        x*=y;
    }
    void o(int x)
    {
        if(x<0)
        {
            p('-');
            x=-x;
        }
        if(x>9)o(x/10);
        p(x%10+'0');
    }
    int main()
    {
        in(n);
        For(i,1,n)
        in(a[i]),b[i]=a[i];
        sort(b+1,b+n+1);
        m=unique(b+1,b+n+1)-b-1;
        For(i,1,n)
          {
              r=0;
              For(j,1,m)
            {
                while(r&&f[i-1][j]<=f[i-1][q[r]])r--;
                q[++r]=j;
                f[i][j]=f[i-1][q[1]]+abs(a[i]-b[j]);
            }
          }
        ans=inf;
        For(i,1,m)
        ans=min(ans,f[n][i]);
        For(i,1,n)
          For(j,1,n)
            f[i][j]=0;
        For(i,1,n)
          {
              r=0;
              For(j,1,m)
            {
                while(l<=r&&f[i-1][j]>=f[i-1][q[r]])r--;
                q[++r]=j;
                f[i][j]=f[i-1][q[1]]+abs(a[i]-b[m]);
            }
          }
        ans=min(ans,f[n][m]);
        o(ans);
         return 0;
    }

    考场贪心骗分代码:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<queue>
      4 #include<algorithm>
      5 #include<cmath>
      6 #include<ctime>
      7 #include<cstring>
      8 #define inf 2147483647
      9 #define For(i,a,b) for(register int i=a;i<=b;i++)
     10 #define p(a) putchar(a)
     11 #define g() getchar()
     12 //by war
     13 //2017.10.18
     14 using namespace std;
     15 int n;
     16 int Max;
     17 int last;
     18 int a[2010];
     19 int d[2010];
     20 bool b[2010];
     21 int p[2010];
     22 int f[2010];
     23 int ans[5];
     24 void in(int &x)
     25 {
     26     int y=1;
     27     char c=g();x=0;
     28     while(c<'0'||c>'9')
     29     {
     30     if(c=='-')
     31     y=-1;
     32     c=g();
     33     }
     34     while(c<='9'&&c>='0')x=x*10+c-'0',c=g();
     35     x*=y;
     36 }
     37 void o(int x)
     38 {
     39     if(x<0)
     40     {
     41         p('-');
     42         x=-x;
     43     }
     44     if(x>9)o(x/10);
     45     p(x%10+'0');
     46 }
     47 
     48 void LIS()
     49 {
     50     For(i,1,n)
     51     f[i]=1,d[i]=0;
     52     For(i,1,n)
     53       {
     54           For(j,1,i-1)
     55         {
     56             if(a[j]<=a[i])
     57             {
     58                 if(f[j]+1>f[i])
     59                 {
     60                     f[i]=f[j]+1;
     61                     d[i]=j;
     62                 }
     63             }
     64         }
     65         if(Max<f[i])
     66         {
     67             Max=f[i];
     68             last=i;
     69         }
     70       }
     71       int ft;
     72       for(ft=last;d[ft]!=0;ft=d[ft])
     73       b[ft]=true;
     74       for(int i=ft-1;i>=1;i--)
     75       {
     76           ans[0]+=abs(p[i]-p[i+1]);
     77           p[i]=p[i+1];
     78       }
     79       For(i,ft+1,n)
     80       if(!b[i])
     81       {
     82           ans[0]+=abs(p[i]-p[i-1]);
     83           p[i]=p[i-1];
     84       }
     85 }
     86 
     87 void LRS()
     88 {
     89     Max=0;
     90     For(i,1,n)
     91     f[i]=1,b[i]=false,d[i]=0;
     92     For(i,1,n)
     93       {
     94           For(j,1,i-1)
     95         {
     96             if(a[j]>=a[i])
     97             {
     98                 if(f[j]+1>f[i])
     99                 {
    100                     f[i]=f[j]+1;
    101                     d[i]=j;
    102                 }
    103             }
    104         }
    105         if(Max<f[i])
    106         {
    107             Max=f[i];
    108             last=i;
    109         }
    110       }
    111       int ft;
    112       for(ft=last;d[ft]!=0;ft=d[ft])
    113       b[ft]=true;
    114       for(int i=ft-1;i>=1;i--)
    115       {
    116           ans[1]+=abs(p[i]-p[i+1]);
    117           p[i]=p[i+1];
    118       }
    119       For(i,ft+1,n)
    120       if(!b[i])
    121       {
    122           ans[1]+=abs(p[i]-p[i-1]);
    123           p[i]=p[i-1];
    124       }
    125 }
    126 
    127 int main()
    128 {
    129 //    freopen("grading.in","r",stdin);
    130 //    freopen("grading.out","w",stdout);
    131     in(n);
    132     For(i,1,n)
    133     in(a[i]),p[i]=a[i];
    134     LIS();
    135     For(i,1,n)
    136     p[i]=a[i];
    137     LRS();
    138     o(min(ans[0],ans[1]));
    139      return 0;
    140 }
    View Code
  • 相关阅读:
    WHMCS系统API调用
    Zend Guard Loader/Zend Loader是干什么的
    代理IP收集
    Jenkins 2.x版本的节点配置选项更新
    Visual Studio 2015 未响应/已停止工作的问题解决
    Visual Studio多版本进行切换的研究
    商城产品如何应对多个客户不同的需求修改并发布对应客户的文件
    Visual Studio插件
    微软注册dll在dotnet开发时起到缓存的作用
    Visual Studio 2015出现Cannot find one or more components. Please reinstall the application.的问题解决
  • 原文地址:https://www.cnblogs.com/war1111/p/7688049.html
Copyright © 2020-2023  润新知