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;
    }
    

      

     

     

     

     

     

  • 相关阅读:
    python实用库:PrettyTable 学习
    centos启动错误:Inodes that were part of a corrupted orphan linked list found.
    C++:in namespace 'std' does not name a template type
    小程序实现单词查询搜索及搜索的历史记录
    小程序图片懒加载较完美解决方案
    下载文件到本地解压压缩包出现文件损坏,报错问题已解决
    彻底理解cookie,session,token
    vue全家桶(Vue+Vue-router+Vuex+axios)(Vue+webpack项目实战系列之二)
    与关系型数据库相比,MongoDB的优缺点
    漫谈JS 的继承方式
  • 原文地址:https://www.cnblogs.com/zhangbuang/p/11253761.html
Copyright © 2011-2022 走看看