zoukankan      html  css  js  c++  java
  • 【BZOJ】【1049】【HAOI2006】数字序列

    DP


      第一问比较水……a[i]-=i 以后就变成最长不下降子序列问题了,第二问这个结论好神奇,考试的时候怎么破?大胆猜想,不用证明?TAT

      题解:http://pan.baidu.com/share/link?uk=2651016602&shareid=1490516411

    没有将a[0]置为-INF在BZOJ上WA了……so sad……

     1 /**************************************************************
     2     Problem: 1049
     3     User: Tunix
     4     Language: C++
     5     Result: Accepted
     6     Time:260 ms
     7     Memory:2912 kb
     8 ****************************************************************/
     9  
    10 //BZOJ 1049
    11 #include<vector>
    12 #include<cstdio>
    13 #include<cstring>
    14 #include<cstdlib>
    15 #include<iostream>
    16 #include<algorithm>
    17 #define rep(i,n) for(int i=0;i<n;++i)
    18 #define F(i,j,n) for(int i=j;i<=n;++i)
    19 #define D(i,j,n) for(int i=j;i>=n;--i)
    20 #define pb push_back
    21 using namespace std;
    22 inline int getint(){
    23     int v=0,sign=1; char ch=getchar();
    24     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
    25     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
    26     return v*sign;
    27 }
    28 const int N=35010,INF=~0u>>2;
    29 typedef long long LL;
    30 /******************tamplate*********************/
    31 int head[N],to[N],next[N],cnt;
    32 void ins(int x,int y){
    33     to[++cnt]=y; next[cnt]=head[x]; head[x]=cnt;
    34 }
    35 int n,a[N],b[N],f[N],len;
    36 int Find(int x){
    37     int l=1,r=len,mid,ans=0;
    38     while(l<=r){
    39         mid=l+r>>1;
    40         if (b[mid]<=x) ans=mid,l=mid+1;
    41         else r=mid-1;
    42     }
    43     return ans+1;
    44 }
    45 LL g[N],sum1[N],sum2[N];
    46 void solve2(){
    47     D(i,n,0){
    48         ins(f[i],i);
    49         g[i]=1LL<<60;
    50     }
    51     g[0]=0; 
    52     a[0]=-1<<30;//这句必须有,不然在BZOJ上会WA……
    53     F(x,1,n)
    54         for(int i=head[f[x]-1];i;i=next[i]){//枚举从哪个地方转移过来
    55             if (to[i]>x) break;
    56             if (a[to[i]]>a[x]) continue;
    57             for(int k=to[i];k<=x;k++)
    58                 sum1[k]=abs(a[k]-a[to[i]]),sum2[k]=abs(a[x]-a[k]);
    59             for(int k=to[i]+1;k<=x;k++)
    60                 sum1[k]+=sum1[k-1],sum2[k]+=sum2[k-1];
    61             for(int k=to[i];k<x;k++)
    62                 g[x]=min(g[x],g[to[i]]+sum1[k]-sum1[to[i]]+sum2[x]-sum2[k]);
    63         }
    64     cout <<g[n]<<endl;
    65 }
    66 int main(){
    67     n=getint();
    68     F(i,1,n) a[i]=getint()-i;
    69     a[++n]=1<<30;
    70     F(i,1,n){
    71         int x=Find(a[i]);
    72         f[i]=x; b[x]=a[i];
    73         if (x>len) len=x;
    74     }
    75 //  F(i,1,n) printf("%d ",f[i]);puts("");
    76     printf("%d
    ",n-f[n]);//task 1 end
    77     solve2();
    78     return 0;
    79 }
    View Code

    1049: [HAOI2006]数字序列

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 1022  Solved: 410
    [Submit][Status][Discuss]

    Description

    现在我们有一个长度为n的整数序列A。但是它太不好看了,于是我们希望把它变成一个单调严格上升的序列。但是不希望改变过多的数,也不希望改变的幅度太大。

    Input

    第一行包含一个数n,接下来n个整数按顺序描述每一项的键值。

    Output

    第一行一个整数表示最少需要改变多少个数。 第二行一个整数,表示在改变的数最少的情况下,每个数改变的绝对值之和的最小值。

    Sample Input

    4
    5 2 3 5

    Sample Output

    1
    4

    HINT

    【数据范围】

    90%的数据n<=6000。

    100%的数据n<=35000。

    保证所有数列是随机的。

    Source

    [Submit][Status][Discuss]
  • 相关阅读:
    Nginx负载均衡+代理+ssl+压力测试
    Nginx配置文件详解
    HDU ACM 1690 Bus System (SPFA)
    HDU ACM 1224 Free DIY Tour (SPFA)
    HDU ACM 1869 六度分离(Floyd)
    HDU ACM 2066 一个人的旅行
    HDU ACM 3790 最短路径问题
    HDU ACM 1879 继续畅通工程
    HDU ACM 1856 More is better(并查集)
    HDU ACM 1325 / POJ 1308 Is It A Tree?
  • 原文地址:https://www.cnblogs.com/Tunix/p/4432882.html
Copyright © 2011-2022 走看看