博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【bzoj1786】[Ahoi2008]Pair 配对 dp
阅读量:4979 次
发布时间:2019-06-12

本文共 1580 字,大约阅读时间需要 5 分钟。

题目描述

输入

输出

样例输入

5 4

4 2 -1 -1 3

样例输出

4


题解

dp

首先有个结论:填入的数一定是单调不降的。

证明:假设$i<j$,$a_i>a_j$,那么交换$a_i$和$a_j$,对逆序对总数产生的影响只有$[i+1,j-1]$这段区间及$i$和$j$。对于中间的部分,交换后$i$位置上的数变小,使得与中间位置的数产生的逆序对数不增;交换后$j$位置上的数变大,同样使得与中间位置的数产生的逆序对数不增;交换了$a_i$和$a_j$,使得总逆序对数-1。所以一定不如交换后更优。

那么产生的逆序对只有两种情况:原来确定的数之间、原来确定的数与填入的数之间。

于是我们就可以dp:设$f[i][j]$表示枚举到位置$i$,上一个填入的数是$j$的最小逆序对数。那么如果$i$位置的数是确定的,只需要计算答案,并把$f[i-1]$的状态复制过来。

如果$i$位置的数不是确定的,那么枚举这个数为$t$,则$f[i][t]=min(f[i-1][j])+ans[i][t]\ (j\le t)$,其中$ans[i][t]$为i位置填入t产生的逆序对数。

那么对于前面的部分维护一个前缀最小值即可,后面的部分由于k很小,所以使用二维前缀和与后缀和维护,$O(1)$查询。

最后的答案即为$f[n][t]$,总的时间复杂度为$O(nk)$

#include 
#include
#include
using namespace std;int a[10010] , f[10010][110] , s1[10010][110] , s2[10010][110];int main(){ int n , k , i , j , ans = 1 << 30 , tmp; scanf("%d%d" , &n , &k); for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &a[i]); for(i = 1 ; i <= n ; i ++ ) for(j = k ; j >= 1 ; j -- ) s1[i][j] = s1[i - 1][j] + s1[i][j + 1] - s1[i - 1][j + 1] + (a[i] == j); for(i = n ; i >= 1 ; i -- ) for(j = 1 ; j <= k ; j ++ ) s2[i][j] = s2[i + 1][j] + s2[i][j - 1] - s2[i + 1][j - 1] + (a[i] == j); memset(f , 0x3f , sizeof(f)) , f[0][1] = 0; for(i = 1 ; i <= n ; i ++ ) { if(~a[i]) for(j = 1 ; j <= k ; j ++ ) f[i][j] = f[i - 1][j] + s1[i - 1][a[i] + 1]; else for(j = 1 , tmp = 1 << 30 ; j <= k ; j ++ ) tmp = min(tmp , f[i - 1][j]) , f[i][j] = tmp + s1[i - 1][j + 1] + s2[i + 1][j - 1]; } for(i = 1 ; i <= k ; i ++ ) ans = min(ans , f[n][i]); printf("%d\n" , ans); return 0;}

 

 

转载于:https://www.cnblogs.com/GXZlegend/p/7134214.html

你可能感兴趣的文章
Java中instanceof关键字的用法总结
查看>>
引用类型-Function类型
查看>>
(转)Android 仿订单出票效果 (附DEMO)
查看>>
数据库多张表导出到excel
查看>>
微信小程序去除button默认样式
查看>>
Where does Visual Studio look for C++ Header files?
查看>>
Java打包可执行jar包 包含外部文件
查看>>
Windows Phone开发(37):动画之ColorAnimation
查看>>
js中escape,encodeURI,encodeURIComponent 区别(转)
查看>>
sass学习笔记-安装
查看>>
Flask (二) cookie 与 session 模型
查看>>
修改添加网址的教程文件名
查看>>
[BZOJ 1017][JSOI2008]魔兽地图DotR(树形Dp)
查看>>
裁剪图片
查看>>
数据结构实习 problem L 由二叉树的中序层序重建二叉树
查看>>
VS中展开和折叠代码
查看>>
如何确定VS编译器版本
查看>>
设置PL/SQL 快捷键
查看>>
个人阅读作业7
查看>>
转载:深入浅出Zookeeper
查看>>