zoukankan      html  css  js  c++  java
  • 【2018南京】 Tournament (dp + 决策单调性 + wqs 二分)

    There are NN villagers (including the village chief) living in Number Village. Interestingly, all of their houses lie on a straight line. The house of the ii-th villager (0leq i<N0i<N) lies exactly a_iaikilometers to the east of the village chief's house. (For simplicity, the 00-th villager is the village chief, so a_0=0a0=0.)

    Recently, a tournament is going to be held in Number Village, in which everyone in the village will participate.

    For the convenience of villagers, the organizer plans to build KK stadiums. The stadium can be built anywhere in the village, even at the same place as any villager's house.

    However, the organizer wants the traffic cost to be minimized. The traffic cost is defined by sum_{i=0}^{N-1} min_{j=0}^{K-1} D(a_i, s_j)i=0N1minj=0K1D(ai,sj), where D(a_i, s_j)D(ai,sj) is the distance between the ii-th villager's house and the jj-th stadium.

    Your task is to calculate the minimal traffic cost (rounded down to the nearest integer), given N, KN,K and a_iai.

    Input

    The first line contains two positive integers N,KN,K (Kleq Nleq 3 imes 10^ 5KN3×105).

    The second line contains NN non-negative integers a_0,a_1,cdots,a_{N-1}a0,a1,,aN1 (0=a_0<a_1<cdots<a_{N-1}leq 10^ 90=a0<a1<<aN1109).

    Output

    Print a single integer  ext{---}— the minimal traffic cost rounded down to the nearest integer.

    样例输入1

    5 2
    0 4 7 9 10

    样例输出1

    7

    样例输入2

    9 3
    0 1 10 11 20 21 22 30 32

    样例输出2

    23

    题目来源

    ACM-ICPC Nanjing Onsite 2018

     

    SOLUTION:

    我这份题解并没有a,可能是二分的地方常数太大导致T了,但是可以当作模板

    wqs二分之后,变成了O^2的dp,然后使用单调队列来进行优化

    一类导数递增求最小值,或者导数递减求最大值,需要使用单调队列

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 0x3f3f3f3f3f3f3f3f
    #define N 300010
    
    ll n,k,s[N],f[N],w[N],ans=0;
    int q[N];
    
    ll a[N]; int isx[N];
    inline ll calc(int &j,int &i)
    {
        int mid=i+j+1>>1;
        ll now=s[mid]-s[mid-1];
      //  return f[j]+s[i]+s[j]-2*s[mid]+((i-j)&1?now:0);
        mid=i+j+1>>1;
        return f[j]+(s[i]-s[mid]-(i-mid)*a[mid])+((mid-j-1)*a[mid]-(s[mid-1]-s[j]));
    
    }
    inline bool better(int &k1,int &k2,int &i)
    {
        ll val1=calc(k1,i),val2=calc(k2,i);
        if(val2<val1)
            return 1;
        if(val1<val2)
            return 0;
        return w[k2]<=w[k1];
    }
    
    inline int bound(int &a,int &b,int o)
    {
        int l=b+1,r=o?o:n+1,ans=r+1;
        while(l<=r)
        {
            int mid=l+r>>1;
           // if(calc(a,mid)>=calc(b,mid))ans=mid,r=mid-1;
            if(better(a,b,mid))ans=mid,r=mid-1;
            else l=mid+1;
        } return ans;
    }
    
    inline int  jud(ll mid)
    {
        int qh=1,qt=0;
        q[++qt]=0;
        for(int i=1;i<=n;++i)
        {
            while(qh<qt&&isx[qh]<=i)++qh;
            f[i]=calc(q[qh],i)+mid;
            w[i]=w[q[qh]]+1;
            while(qh<qt&&isx[qt-1]>=bound(q[qt],i,isx[qt-1]+1))
                --qt;
            isx[qt]=bound(q[qt],i,0);
            q[++qt]=i;
        }
        return w[n];
    }inline int read()
    {
    	int X=0; bool flag=1; char ch=getchar();
    	while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}
    	while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}
    	if(flag) return X;
    	return ~(X-1);
    }
    
    signed main()
    {
        n=read(); k=read();
            ans=0;
            for(int i=1;i<=n;i++)isx[i]=0;
            for(ll i=1;i<=n;i++)
            {
                s[i]=read();
                a[i]=s[i];
                s[i]+=s[i-1];
            }
            ll l=0,r=s[n];
            while(l<=r)
            {
                ll mid=l+r>>1;
                if(jud(mid)<=k)
                {
                    r=mid-1;
                    ans=f[n]-k*mid;
                }
                else
                    l=mid+1;
            }
            printf("%lld
    ",ans);
    
        return 0;
    }
    

      

     

     

     

     

     

  • 相关阅读:
    毕业半年,码过5个城市
    Java实现office文档与pdf文档的在线预览功能
    挺过最艰难的2018,我终将长大
    dubbo源码分析(一)-从xml到我们认识的Java对象
    沉淀一年,我想推荐这些书给你
    Java动态代理(一)
    Java工程师成神之路思维导图
    Java
    阿里巴巴Java开发手册思维导图
    Mysql的排他锁和共享锁
  • 原文地址:https://www.cnblogs.com/zhangbuang/p/11253761.html
Copyright © 2011-2022 走看看