zoukankan      html  css  js  c++  java
  • 【BZOJ5311/CF321E】贞鱼/Ciel and Gondolas(动态规划,凸优化,决策单调性)

    【BZOJ5311/CF321E】贞鱼/Ciel and Gondolas(动态规划,凸优化,决策单调性)

    题面

    BZOJ
    CF
    洛谷
    辣鸡BZOJ卡常数!!!!!!
    辣鸡BZOJ卡常数!!!!!!
    辣鸡BZOJ卡常数!!!!!!
    所以我程序在BZOJ过不了

    题解

    朴素的按照(k)划分阶段的(dp)可以在(CF)上过的。
    发现当选择的(k)增长时,减少的代价也越来越少,
    所以可以凸优化一下,这样复杂度少个(k)
    变成了(O(nlogw))

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define MAX 4040
    #define double int
    inline int read()
    {
        int x=0;bool t=false;char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=true,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return t?-x:x;
    }
    struct Node{int x,l,r;}Q[MAX];
    int h,t;
    int n,K,s[MAX][MAX];
    int f[MAX],g[MAX];
    int Trans(int i,int j,int C){return f[j]+(s[j][j]-s[i][j]*2+s[i][i])/2+C;}
    void calc(int C)
    {
        f[0]=g[0]=h=0;Q[h=t=1]=(Node){0,1,n};
        for(int i=1;i<=n;++i)
        {
            while(h<t&&Q[h].r<i)++h;
            f[i]=Trans(i,Q[h].x,C);g[i]=g[Q[h].x]+1;
            while(h<t&&i>=Q[h].r)++h;
    		if(Trans(n,Q[t].x,C)<=Trans(n,i,C))continue;
    		while(h<t&&Trans(Q[t].l,Q[t].x,C)>Trans(Q[t].l,i,C))--t;
    		int l=Q[t].l,r=Q[t].r,ret=Q[t].r+1;
            while(l<=r)
            {
                int mid=(l+r)>>1;
                if(Trans(mid,i,C)<Trans(mid,Q[t].x,C))ret=mid,r=mid-1;
                else l=mid+1;
            }
            if(ret>n)continue;
            Q[t].r=ret-1;Q[++t]=(Node){i,ret,n};
        }
    }
    int main()
    {
        n=read();K=read();
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j)
                s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+read();
        int l=0,r=s[n][n],ans=1e9;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            calc(mid);
            if(g[n]>K)l=mid+1;
            else r=mid-1,ans=f[n]-K*mid;
        }
        cout<<ans<<endl;
        return 0;
    }
    
    
  • 相关阅读:
    Maven版本管理
    ArrayList集合实现RandomAccess接口有何作用?为何LinkedList集合却没实现这接口
    java常用集合框架关系
    重写equals和hashCode
    项目的继承和聚合详解
    Installation Manager1.8安装
    关于java按位操作运算
    正数负数的二进制表示
    springboot问题排解
    int和Integer有什么区别
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9430055.html
Copyright © 2011-2022 走看看