zoukankan      html  css  js  c++  java
  • [BZOJ5125]小Q的书架(决策单调性+分治DP+树状数组+莫队?)

    (O(n^2k))比较好想

    (dp[i][j]=minlimits_{k<i}(dp[k][j-1]+w(k+1,i)))

    (w)就是逆序对个数。

    打表发现有决策单调性。

    但是我们发现逆序对个数不能很快的算,所以单调队列用不了了。

    考虑分治,

    (solve(l,r,L,R,k))表示要计算的部位为([l,r]),可能决策点位于([L,R])内,于是暴力算出(mid)的最优决策点(p),两边递归下去dp

    /*
    @Date    : 2019-08-16 21:14:43
    @Author  : Adscn (adscn@qq.com)
    @Link    : https://www.cnblogs.com/LLCSBlog
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define IL inline
    #define RG register
    #define int long long
    #define gi getint()
    #define gc getchar()
    #define File(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
    IL int getint()
    {
    	RG int xi=0;
    	RG char ch=gc;
    	bool f=0;
    	while(ch<'0'||ch>'9')ch=='-'?f=1:f,ch=gc;
    	while(ch>='0'&&ch<='9')xi=(xi<<1)+(xi<<3)+ch-48,ch=gc;
    	return f?-xi:xi;
    }
    template<typename T>
    IL void pi(T k,char ch=0)
    {
    	if(k<0)k=-k,putchar('-');
    	if(k>=10)pi(k/10,0);
    	putchar(k%10+'0');
    	if(ch)putchar(ch);
    }
    const int N=4e4+7;
    int n,K,sum;
    int c[N],a[N],f[N][11];
    void add(int k,int x){for(;k<=n;k+=k&-k)c[k]+=x;}
    int qry(int x){int ans=0;for(;x;x-=x&-x)ans+=c[x];return ans;}
    int L,R;
    void move(int l,int r){
    	while(L<l)sum-=qry(a[L]-1),add(a[L++],-1);
        while(L>l)sum+=qry(a[L-1]-1),add(a[--L],1);
        while(R<r)sum+=R-L+1-qry(a[R+1]),add(a[++R],1);
        while(R>r)sum-=R-L+1-qry(a[R]),add(a[R--],-1);
    }
    void solve(int l,int r,int L,int R,int now)
    {
    	if(l>r)return;
    	int mid=(l+r)>>1,p=L;
    	for(int i=L;i<=min(mid-1,R);++i)
    	{
    		move(i+1,mid);
    		if(f[i][now-1]+sum<f[mid][now])f[mid][now]=f[i][now-1]+sum,p=i;
    	}
    	solve(l,mid-1,L,p,now);
    	solve(mid+1,r,p,R,now);
    }
    signed main(void)
    {
    	n=gi,K=gi;
    	for(int i=1;i<=n;++i)a[i]=gi;
    	memset(f,127,sizeof f);
    	L=1,R=0;
    	for(int i=1;i<=n;++i)move(1,i),f[i][1]=sum;
    	for(int i=2;i<=K;++i)solve(1,n,1,n,i);
    	pi(f[n][K]);
    	return 0;
    }
    
  • 相关阅读:
    ble_app_hrs心率程序 nrf51822
    2019.05.08 《Linux驱动开发入门与实战》
    函数指针
    typedef
    回调函数
    android2
    android1
    每周总结2
    HTML
    数组(续)
  • 原文地址:https://www.cnblogs.com/LLCSBlog/p/11366472.html
Copyright © 2011-2022 走看看