zoukankan      html  css  js  c++  java
  • CDOJ 594:我要长高 单调队列优化DP

    我要长高

    题目链接:

    http://www.acm.uestc.edu.cn/#/problem/show/594

    题意:

    中文

    题解:

    可以发现数据小些的话是很简单的   dp[i][j](第 i 个人身高为 j 的最小花费)=min(dp[i-1][k]+abs(k-j)*C)+(h[i]-j)^2

    由于数据略大,会发现时间复杂度大约是1e9的,由于状态转移方程满足用单调队列优化的条件,直接用单调队列优化就行了

    (其实只需要用个值记录下动态的最小值就好了=_=)

    代码

    #include<stdio.h>
    #define mmin(a,b) (a<b?a:b)
    const int M=1e2+1;
    int dp[2][M],Que[101];
    const int inf=2e9+1;
    void solve()
    {
      int n,c,h,tail,head,ch=0;
      while(~scanf("%d%d",&n,&c))
      {
        scanf("%d",&h);
        for(int i=0;i<=100;++i)
        dp[ch][i]=i<h?inf:(h-i)*(h-i);
        for(int i=1;i<n;++i)
        {
          ch=1-ch;
          scanf("%d",&h);
          tail=0,head=1;
          for(int j=0;j<=100;++j)//前一人身高小于j 当前人身高等于 j
          {
            while(dp[1-ch][j]-j*c<=Que[tail]&&tail>=head)--tail;//这一部分也可以改为 S=min(S,dp[1-ch][j]-j*c) 0.0就不需要开队列了
            Que[++tail]=dp[1-ch][j]-j*c;//与0的差值
            if(j<h)dp[ch][j]=inf;
            else dp[ch][j]=Que[head]+(h-j)*(h-j)+j*c;
          }
          tail=0,head=1;
          for(int j=100;j>=0;--j)
          {
            while(dp[1-ch][j]+j*c<=Que[tail]&&tail>=head)--tail;
            Que[++tail]=dp[1-ch][j]+j*c;
            if(j>=h)dp[ch][j]=mmin(dp[ch][j],Que[head]+(h-j)*(h-j)-j*c);
          }      
        }
        int res=dp[ch][h];
        for(int i=h+1;i<=100;++i)
        if(dp[ch][i]<res)res=dp[ch][i];
        printf("%d ",res);
      }
    }


    int main()
    {
      solve();
      return 0;
    }

     
     
  • 相关阅读:
    Eclipse中支持js提示
    数据库命名规则
    JavaWeb 命名规则
    Ajax&json
    js中,var 修饰变量名和不修饰的区别
    javaScript知识点
    Bootstrap 栅格系统
    文本框如果不输入任何内容提交过后是一个空字符串还是null
    根据汇总数量依次扣减的SQL新语法
    asp.net中使用forms验证
  • 原文地址:https://www.cnblogs.com/kiuhghcsc/p/6020721.html
Copyright © 2011-2022 走看看