zoukankan      html  css  js  c++  java
  • p2501 [HAOI2006]数字序列

    传送门

    分析

    https://www.luogu.org/blog/FlierKing/solution-p2501

    对于第二问的感性理解就是有上下两条线,一些点在上面的线的上面或者下面的线的下面,然后看它们变成哪个线的位置更优

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    #define int long long
    const int inf = 1e9+7;
    int a[100100],d[100100],dp[100100],ddp[100100],sum1[100100],sum2[100100];
    vector<int>v[100100];
    signed main(){
        int n,m,i,j,k,x,Ans=0;
        scanf("%lld",&n);
        for(i=1;i<=n;i++)scanf("%lld",&x),a[i]=x-i;
        a[++n]=inf;d[0]=a[0]=-inf;
        for(i=1;i<=n;i++)d[i]=inf;
        for(i=1;i<=n;i++){
          int p=upper_bound(d,d+Ans+1,a[i])-d;
          Ans=max(Ans,p);
          dp[i]=p;
          d[p]=a[i];
        }
        v[0].push_back(0);
        for(i=1;i<=n;i++)v[dp[i]].push_back(i);
        printf("%lld
    ",n-Ans);
        ddp[0]=0;
        for(i=1;i<=n;i++)ddp[i]=inf;
        for(i=1;i<=n;i++)
          for(j=0;j<v[dp[i]-1].size();j++){
            int to=v[dp[i]-1][j];
            if(to>i)break;
            if(a[to]>a[i])continue;
            for(k=to;k<=i;k++)sum1[k]=abs(a[k]-a[to]),sum2[k]=abs(a[k]-a[i]);
            for(k=to+1;k<=i;k++)sum1[k]+=sum1[k-1],sum2[k]+=sum2[k-1];
            for(k=to;k<i;k++)
              ddp[i]=min(ddp[i],ddp[to]+sum1[k]-sum1[to]+sum2[i]-sum2[k]);
          }
        printf("%lld
    ",ddp[n]);
        return 0;
    }
  • 相关阅读:
    gson和fastjson
    Hive和HBase的区别
    mac 比较两个文件
    mysql 查找在另一张表不存在的数据
    mysql 根据一张表更新另一张表
    shell调试
    目标
    百度在线面试总结
    20170109| javascript记录
    php-fpm问题
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/10354437.html
Copyright © 2011-2022 走看看