题意:N个数,按顺序划分为K组,使得逆序对之和最小。

思路:之前能用四边形不等式写的,一般网上都还有DP单调性分治的做法,今天也尝试用后者写(抄)了一遍。即:

分成K组,我们进行K-1次分治,get(l,r,L,R)中如果mid位置的最优解来自MID,那么分别以mid和MID和分界线,有get(l,mid-1,L,MID);get(mid+1,r,MID,R);

区间逆序对没有什么特别高效的方法,我们用莫对跑ok了。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
int a[maxn],sum[maxn],dp[maxn],ans[maxn],N,K,ql,qr,cost;
inline int query(int x){int res=;while(x){ res+=sum[x]; x-=(-x)&x;} return res;}
inline void add(int x,int val){while(x<=N){ sum[x]+=val; x+=(-x)&x;} }
inline void move(int l,int r)
{
while(ql>l) cost+=query(a[--ql]-),add(a[ql],);
while(qr<r) cost+=query(N)-query(a[++qr]),add(a[qr],);
while(ql<l) add(a[ql],-),cost-=query(a[ql++]-);
while(qr>r) add(a[qr],-),cost-=query(N)-query(a[qr--]);
}
inline void get(int l,int r,int L,int R)
{
if(l>r) return ;
int mid=(l+r)>>,Mid;
for(int i=min(R+,mid);i>L;i--){
move(i,mid);
if(dp[i-]+cost<ans[mid]) {ans[mid]=dp[i-]+cost; Mid=i-;}
}
get(l,mid-,L,Mid); get(mid+,r,Mid,R);
}
int main()
{
scanf("%d%d",&N,&K);
rep(i,,N) scanf("%d",&a[i]);
rep(i,,N) ans[i]=ans[i-]+query(N)-query(a[i]),add(a[i],);
ql=; qr=N; cost=ans[N];
rep(i,,K){
memcpy(dp,ans,sizeof(ans)); //把上一轮的结果复制
memset(ans,0x3f,sizeof(ans));
get(,N,,N-);
}
printf("%d\n",ans[N]);
return ;
}

我也写了四边形不等式来优化DP,其他部分一样。 然而T了,估计是莫对跑得太多了。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
int a[maxn],sum[maxn],dp[maxn][],pos[maxn][],N,K,ql,qr,cost;
inline int query(int x){int res=;while(x){ res+=sum[x]; x-=(-x)&x;} return res;}
inline void add(int x,int val){while(x<=N){ sum[x]+=val; x+=(-x)&x;} }
inline void move(int l,int r)
{
while(ql>l) cost+=query(a[--ql]-),add(a[ql],);
while(qr<r) cost+=query(N)-query(a[++qr]),add(a[qr],);
while(ql<l) add(a[ql],-),cost-=query(a[ql++]-);
while(qr>r) add(a[qr],-),cost-=query(N)-query(a[qr--]);
}
int main()
{
scanf("%d%d",&N,&K);
rep(i,,N) scanf("%d",&a[i]);
memset(dp,0x3f,sizeof(dp)); dp[][]=;
rep(i,,N) dp[i][]=dp[i-][]+query(N)-query(a[i]),add(a[i],);
ql=; qr=N; cost=dp[N][];
rep(i,,K){
rep(j,,N){
int L=pos[j][i-]?pos[j][i-]:;
int R=pos[j+][i]?pos[j+][i]:N-;
rep(k,L,R) {
if(k>=j) continue;
move(k+,j);
if(dp[j][i]>dp[k][i-]+cost){
dp[j][i]=dp[k][i-]+cost;
pos[j][i]=k;
}
}
}
}
printf("%d\n",dp[N][K]);
return ;
}

BZOJ5125: [Lydsy1712月赛]小Q的书架(DP决策单调性)的更多相关文章

  1. BZOJ5125: [Lydsy1712月赛]小Q的书架【决策单调性优化DP】【BIT】【莫队】【分治】

    小Q有n本书,每本书有一个独一无二的编号,现在它们正零乱地在地上排成了一排. 小Q希望把这一排书分成恰好k段,使得每段至少有一本书,然后把每段按照现在的顺序依次放到k层书架的每一层上去.将所有书都放到 ...

  2. bzoj 5125: [Lydsy1712月赛]小Q的书架

    新学了一波 决策单调性 dp 套路.... 这种dp一般是长这样的 => f[i][j] = max/min  { f[i-1][k] + cost(k+1,j)} ,其中cost函数满足四边形 ...

  3. BZOJ5125 小Q的书架(决策单调性+动态规划+分治+树状数组)

    设f[i][j]为前i个划成j段的最小代价,枚举上个划分点转移.容易想到这个dp有决策单调性,感性证明一下比较显然.如果用单调栈维护决策就不太能快速的求出逆序对个数了,改为使用分治,移动端点时树状数组 ...

  4. [BZOJ5125]小Q的书架(决策单调性+分治DP+树状数组)

    显然有决策单调性,但由于逆序对不容易计算,考虑分治DP. solve(k,x,y,l,r)表示当前需要选k段,待更新的位置为[l,r],这些位置的可能决策点区间为[x,y].暴力计算出(l+r)/2的 ...

  5. 【BZOJ 5125】小Q的书架

    Problem Description 小 \(Q\) 有 \(n\) 本书,每本书有一个独一无二的编号,现在它们正零乱地在地上排成了一排. 小 \(Q\) 希望把这一排书分成恰好 \(k\) 段,使 ...

  6. 【BZOJ5073】[Lydsy十月月赛]小A的咒语 DP(错解)

    [BZOJ5073][Lydsy十月月赛]小A的咒语 题解:沙茶DP,完全不用后缀数组. 用f[i][j]表示用了A的前i个字符,用了j段,最远能匹配到哪.因为显然我们能匹配到的地方越远越好,所以我们 ...

  7. [BZOJ4813][CQOI2017]小Q的棋盘(DP,贪心)

    4813: [Cqoi2017]小Q的棋盘 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 804  Solved: 441[Submit][Statu ...

  8. [NOI2009]诗人小G --- DP + 决策单调性

    [NOI2009]诗人小G 题目描述: 小G是一个出色的诗人,经常作诗自娱自乐. 但是,他一直被一件事情所困扰,那就是诗的排版问题. 一首诗包含了若干个句子,对于一些连续的短句,可以将它们用空格隔开并 ...

  9. [NOI2009]诗人小G(dp + 决策单调性优化)

    题意 有一个长度为 \(n\) 的序列 \(A\) 和常数 \(L, P\) ,你需要将它分成若干段,每 \(P\) 一段的代价为 \(| \sum ( A_i ) − L|^P\) ,求最小代价的划 ...

随机推荐

  1. C# WebSocket解析(收发数据包、分片超长包处理)

    using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptograph ...

  2. max_spare_servers到底是个什么意思?

    pm.max_children=500pm.start_servers=280pm.min_spare_servers=50pm.max_spare_servers=500 把max_spare_se ...

  3. 在win7虚拟机中装sql server---待整理

    本科学数据库的时候,为了做作业,需要在自己电脑上装sql server.但是每次都装不上,总是有各种小问题通不过.最后问学长,才采用了在虚拟机里装数据库的方法,在虚拟机中可以不用担心弄乱本机系统. 为 ...

  4. PowerDesigner用法和技巧

    PowerDesigner是一款功能非常强大的建模工具软件,足以与Rose比肩,同样是当今最著名的建模软件之一.Rose是专攻UML对象模型的建模工具,之后才向数据库建模发展,而PowerDesign ...

  5. Integer 类型数值判断相等的坑

    题目: public static void main(String[] args) { Integer a = 100, b = 100; Integer c = 150, d = 150; Sys ...

  6. Codeforces Round #428 (Div. 2)E. Mother of Dragons

    http://codeforces.com/contest/839/problem/E 最大团裸题= =,用Bron–Kerbosch算法,复杂度大多博客上没有,维基上查了查大约是O(3n/3) 最大 ...

  7. UVA-11374 Airport Express (dijkstra+枚举)

    题目大意:n个点,m条无向边,边权值为正,有k条特殊无向边,起止点和权值已知,求从起点到终点的边权值最小的路径,特殊边最多只能走一条. 题目分析:用两次dijkstra求出起点到任何一个点的最小权值, ...

  8. ie下的bug之button

    场景描述: 现在页面设计是都喜欢自定义按钮样式,某日接收到页面发现在ie下有bug,上代码: <div> <button><span><a href=&quo ...

  9. [Eclipse]Eclipse快捷键

    查看一个方法被谁调用:选中方法名字,Search-->Reference-->Workspace

  10. Linux0.11信号处理详解

    之前在看操作系统信号这一章的时候,一直是云里雾里的,不知道信号到底是个啥玩意儿..比如在看<Unix环境高级编程>时,就感觉信号是个挺神奇的东西.比如看到下面这段代码: #include& ...