zoukankan      html  css  js  c++  java
  • bzoj 1010 (单调决策优化)

       能够非常好的证明单调决策性质。用   记sum[i]=sigma(C[1],C[2].....C[k]);f[i]=sum[i]+i;  c=l-1;

    有转移dp[i]=min( dp[j]+(f[i]-f[jk]-c)^2);  假死 有2个决策j<k, 对于i点。k决策更优秀 于是能够得到

    dp[k]+(f[i]-f[k]-c)^2<dp[j]+(f[i]-f[j]-c)^2;

    对于一个x>i  如果f[x]=f[i]+v;对于决策j,k。若决策k优于决策j  ,必定

     dp[k]+(f[x]-f[k]-c)^2<dp[j]+(f[x]-f[j]-c)^2;

    于是dp[k]+(f[i]+v-f[k]-c)^2<dp[j]+(f[i]-v-f[j]-c)^2;

    仅仅要2v(f[i]-f[k]-c)+v^2<2v(f[i]-f[j]-c)

    优于v>0   f[k]>f[j]  这是必定成立的  ,所以能够非常好的证明单调决策性质。然后能够依据《1D/1D动态规划初步》论文的写法做。


    #include <set>
    #include <map>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <string>
    #include <cctype>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iomanip>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long LL;
    const int inf  = 0x3fffffff;
    const int mmax = 500010;
    LL C[mmax];
    LL dp[mmax];
    LL sum[mmax];
    int n;
    LL L;
    struct node
    {
        int l,r;
        int d;
        node() {}
        node(int l,int r,int d):l(l),r(r),d(d) {}
        void print()
        {
            printf("%d %d %d
    ",l,r,d);
        }
    }Q[mmax];
    LL sqr(LL x)
    {
        return x*x;
    }
    void up(int i,int j)
    {
        dp[i]=dp[j]+sqr(sum[i]-sum[j]+i-j-1-L);
    }
    bool ok(int i,int j,int d)
    {
        return dp[d]+sqr(sum[i]-sum[d]+i-d-1-L)>=dp[j]+sqr(sum[i]-sum[j]+i-j-1-L);
    }
    int find(int l,int r,int j,int d)
    {
        int mid;
        r++;
        while(l<r)
        {
            mid=(l+r)>>1;
            if(ok(mid,j,d))
                r=mid;
            else
                l=mid+1;
        }
        return r;
    }
    void make()
    {
        int head=0,tail=0;
        dp[0]=0;
        Q[tail++]=node(0,n,0);
        for(int i=1;i<=n;i++)
        {
            while(Q[head].r<i)
                head++;
            if(Q[head].l<i)
                Q[head].l=i;
            up(i,Q[head].d);
            int tmp=0;
            while(head<tail)
            {
                if(ok(Q[tail-1].l,i,Q[tail-1].d))
                {
                    tmp=Q[tail-1].l;
                    tail--;
                }
                else
                {
                    tmp=find(Q[tail-1].l,Q[tail-1].r,i,Q[tail-1].d);
                    Q[tail-1].r=tmp-1;
                    break;
                }
            }
            if(tmp<=n)
                Q[tail++]=node(tmp,n,i);
        }
    }
    int main()
    {
    
        while(cin>>n>>L)
        {
            sum[0]=0;
            for(int i=1;i<=n;i++)
            {
                scanf("%lld",&C[i]);
                sum[i]=sum[i-1]+C[i];
            }
            make();
            printf("%lld
    ",dp[n]);
        }
        return 0;
    }
    


  • 相关阅读:
    正则表达式语法
    flask 保存文件到 七牛云
    flask保存 文件到本地
    在文件保存中 os.getcwd() os.listdir() os.makedirs() os.mkdir() xx.join() ... 等函数 的使用介绍
    插件 DataTable 创建列表 render参数的详解与如何传递本行数据id
    日历插件bootstrap-datetimepicker的使用感悟
    Navicat for MySQL 安装和破解
    数据库迁移(创建关联等操作) Target database is not up to date报错
    dataTable之自定义按钮实现全表 复制 打印 导出 重载
    创建简单的表单Demo
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/6937731.html
Copyright © 2011-2022 走看看