【bzoj1831/1786】【AHOI2008】【逆序对】【dp】
来源:互联网 发布:细说php完整版精要版 编辑:程序博客网 时间:2024/05/29 19:21
Description
小可可和小卡卡想到Y岛上旅游,但是他们不知道Y岛有多远。好在,他们找到一本古老的书,上面是这样说的: 下面是N个正整数,每个都在1~K之间。如果有两个数A和B,A在B左边且A大于B,我们就称这两个数为一个“逆序对”。你数一数下面的数字里有多少个逆序对,你就知道Y岛离这里的距离是多少千米了。 比如说,4 2 1 3 3里面包含了5个逆序对:(4, 2), (4, 1), (4, 3), (4, 3), (2, 1)。 可惜的是,由于年代久远,这些数字里有一部分已经模糊不清了,为了方便记录,小可可用“-1”表示它们。比如说,4 2 -1 -1 3 可能原来是4 2 1 3 3,也可能是4 2 4 4 3,也可能是别的样子。 小可可希望知道,根据他们看清楚的这部分数字,能不能推断出这些数字里最少能有多少个逆序对。
Input
第一行两个正整数N和K。第二行N个整数,每个都是-1或是一个在1~K之间的数。
Output
一个正整数,即这些数字里最少的逆序对个数。
Sample Input
5 4
4 2 -1 -1 3
4 2 -1 -1 3
Sample Output
4
HINT
4 2 4 4 3中有4个逆序对。当然,也存在其它方案得到4个逆序对。
数据范围:
100%的数据中,N<=10000,K<=100。
60%的数据中,N<=100。
40%的数据中,-1出现不超过两次。
题解:
首先可以证明-1位置的数一定是单调不降的.
假设相邻的两个-1的位置是(x,y)(a[x]<=a[y]);
如果交换x,y;
对1-x和y-n中的数显然没有影响.
对x-y中大于max(a[x],a[y])和小于min(a[x],a[y])的数显然也没有影响.
但是对x-y中a[x]-a[y]的数,逆序对数显然增加了.
所以交换x,y只会导致逆序对数不降.
所以-1位置的数一定是单调不降的.
然后我们就不用考虑-1之间的逆序对数了.
预处理一下lc[i][j],rc[i][j]和初始答案.
lc[i][j]表示第i个-1选j左边增加的逆序对数.
rc[i][j]表示第i个-1选j右边增加的逆序对数.
然后设f[i][j]表示前i个-1,第i个-1选j最少的逆序对数.
做一个前缀最小值转移就可以做到O(NK)了.
最后答案就是ans+f[-1的个数][k];
代码:
#include<iostream>#include<cstdio>#include<cstring>#define N 10010#define M 110using namespace std;int f[N][M],a[N],p[N],n,m,ans,lc[N][M],rc[N][M],l,r,t;int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=n;i++){ scanf("%d",&a[i]); if (a[i]!=-1){ for (int j=a[i]+1;j<=m;j++) ans+=p[j]; p[a[i]]++;}else r++; } memset(p,0,sizeof(p)); for (int i=1;i<=n;i++) if (a[i]==-1){ l++;lc[l][0]=t; for (int j=1;j<=m;j++) lc[l][j]=lc[l][j-1]-p[j]; }else p[a[i]]++,t++; memset(p,0,sizeof(p));t=0; for (int i=n;i>=1;i--) if (a[i]==-1){ rc[r][0]=0; for (int j=1;j<=m;j++) rc[r][j]=rc[r][j-1]+p[j-1]; r--;}else p[a[i]]++; for (int i=1;i<=l;i++){ for (int j=1;j<=m;j++) f[i][j]=f[i-1][m]+lc[i][j]+rc[i][j]; for (int j=2;j<=m;j++) f[i][j]=min(f[i][j],f[i][j-1]); } cout<<f[l][m]+ans;}
0 0
- 【bzoj1831/1786】【AHOI2008】【逆序对】【dp】
- bzoj1831: [AHOI2008]逆序对 DP
- [DP] BZOJ1831: [AHOI2008]逆序对
- bzoj1831 [AHOI2008]逆序对(dp)
- bzoj1831【AHOI2008】逆序对
- bzoj1831: [AHOI2008]逆序对
- bzoj1831: [AHOI2008]逆序对
- 动态规划 BZOJ1831 [AHOI2008]逆序对
- (bzoj 1831: [AHOI2008]逆序对)<DP>
- 1831: [AHOI2008]逆序对
- bzoj 1831: [AHOI2008]逆序对
- [BZOJ1786&&BZOJ1831]配对 dp
- 逆序对的dp
- BZOJ1831
- bzoj1831
- bzoj 1786 && bzoj 1831: [Ahoi2008]Pair 配对(DP)
- 【bzoj 1786】[Ahoi2008]Pair 配对
- bzoj 1786 [Ahoi2008]Pair 配对
- 前端习惯初养成
- 安装MySql出错问题解决办法
- 在CI框架中如何实现伪静态
- Struts2理解--动态方法和method属性及通配符_默认Action
- hibernate tools--eclipse反向工程
- 【bzoj1831/1786】【AHOI2008】【逆序对】【dp】
- 代码块
- 代码生成器介绍
- Struts2理解——转发和重定向
- Cordova 第三天
- 反射理解1
- 巴什博弈
- Android SurfaceView 的学习(二)
- JSON的使用_检查JSON工具