[BZOJ1786][BZOJ1831]逆序对

试题描述

输入

输出

输入示例

  1. - -

输出示例

  1.  

数据规模及约定

见“输入

题解

首先这题有一个性质,即,填的数从左到右一定不降。证明不妨读者自己yy(提示:用先按降序填,交换后答案一定不会更差的思想证)。

那么新添的数字一定不会造出逆序对了。

然后设计 dp,设 f(i, j) 表示考虑前 i 个打“-1”的位置,最后一个(第 i 个)位置填写数字 j 时,与已经固定的数字产生最少的逆序对数。

有 f(i, j) = min{ f(i-1, x) | 0 < x ≤ j } + lager(pos[i], j) + smaller(pos[i], j),其中,pos[i] 表示第 i 个“-1”在原数列中的位置,larger(i, j) 表示第 1~i-1 个已知数中比 j 大的数的个数,smaller(i, j) 表示第 i+1~n 个已知数中比 j 小的数的个数。

答案是 min{ f(cnt, x) | 0 < x ≤ k } + ans,其中 cnt 表示 -1 的个数,ans 表示已知数字中逆序对个数。

  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. #include <cmath>
  5. #include <algorithm>
  6. #include <stack>
  7. #include <vector>
  8. #include <queue>
  9. #include <cstdlib>
  10. using namespace std;
  11.  
  12. const int BufferSize = 1 << 16;
  13. char buffer[BufferSize], *Head, *tail;
  14. inline char Getchar() {
  15. if(Head == tail) {
  16. int l = fread(buffer, 1, BufferSize, stdin);
  17. tail = (Head = buffer) + l;
  18. }
  19. return *Head++;
  20. }
  21. int read() {
  22. int x = 0, f = 1; char c = Getchar();
  23. while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
  24. while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
  25. return x * f;
  26. }
  27.  
  28. #define maxn 10010
  29. #define maxk 110
  30. #define oo 2147483647
  31. int n, k, A[maxn], f[maxn][maxk], la[maxn][maxk], sm[maxn][maxk], pos[maxn], cnt;
  32.  
  33. int c[maxn];
  34. void add(int x) { for(; x <= k; x += x & -x) c[x]++; return ; }
  35. int sum(int x) { int res = 0; for(; x; x -= x & -x) res += c[x]; return res; }
  36.  
  37. int main() {
  38. n = read(); k = read();
  39. for(int i = 1; i <= n; i++) A[i] = read();
  40.  
  41. int ans = 0;
  42. for(int i = n; i; i--) {
  43. if(A[i] >= 0) add(A[i]), ans += sum(A[i] - 1);
  44. for(int j = 2; j <= k; j++) sm[i][j] = sum(j - 1);
  45. }
  46. memset(c, 0, sizeof(c));
  47. for(int i = 1; i <= n; i++) {
  48. if(A[i] >= 0) add(k - A[i] + 1);
  49. else pos[++cnt] = i;
  50. for(int j = 1; j < k; j++) la[i][j] = sum(k - j);
  51. }
  52. for(int i = 1; i <= k; i++) f[0][i] = 0;
  53. for(int i = 1; i <= cnt; i++)
  54. for(int j = 1; j <= k; j++) {
  55. f[i][j] = oo;
  56. for(int x = 1; x <= j; x++) f[i][j] = min(f[i][j], f[i-1][x]);
  57. f[i][j] += la[pos[i]][j] + sm[pos[i]][j];
  58. }
  59.  
  60. int sum = oo;
  61. for(int i = 1; i <= k; i++) sum = min(sum, f[cnt][i]);
  62. printf("%d\n", ans + sum);
  63.  
  64. return 0;
  65. }

[BZOJ1786][BZOJ1831]逆序对的更多相关文章

  1. bzoj1831 逆序对 (dp+树状数组)

    注意到,所有的-1应该是一个不降的序列,否则不会更优那就先求出来不是-1的的逆序对个数,然后设f[i][j]表示第i个-1放成j的前i个-1带来的最小逆序对数量这个可以树状数组来求 #include& ...

  2. 洛谷 P4280 bzoj1786 [AHOI2008]逆序对(dp)

    题面 luogu bzoj 题目大意: 给你一个长度为\(n\)的序列,元素都在\(1-k\)之间,有些是\(-1\),让你把\(-1\)也变成\(1-k\)之间的数,使得逆序对最多,求逆序对最少是多 ...

  3. bzoj1831: [AHOI2008]逆序对(DP+双精bzoj1786)

    1831: [AHOI2008]逆序对 Description 小可可和小卡卡想到Y岛上旅游,但是他们不知道Y岛有多远.好在,他们找到一本古老的书,上面是这样说的: 下面是N个正整数,每个都在1~K之 ...

  4. 逆序对的相关问题:bzoj1831,bzoj2431

    先从简单一点的bzoj2431入手: n个数1~n已经限定了,所以 对于1~i-1,新加入i,最多可以增加i-1个逆序对,最少增加0个逆序对 f[i,j]表示1~i形成的序列逆序对为j的方案数 比较容 ...

  5. 【BZOJ1831】[AHOI2008]逆序对(动态规划)

    [BZOJ1831][AHOI2008]逆序对(动态规划) 题面 BZOJ 洛谷 题解 显然填入的数拎出来是不降的. 那么就可以直接大力\(dp\). 设\(f[i][j]\)表示当前填到了\(i\) ...

  6. BZOJ1786 [Ahoi2008]Pair 配对 动态规划 逆序对

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1786 题意概括 给出长度为n的数列,只会出现1~k这些正整数.现在有些数写成了-1,这些-1可以变 ...

  7. BZOJ1831: [AHOI2008]逆序对

    1831: [AHOI2008]逆序对 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 341  Solved: 226[Submit][Status] ...

  8. BZOJ1786: [Ahoi2008]Pair 配对/1831: [AHOI2008]逆序对

    这两道题是一样的. 可以发现,-1变成的数是单调不降. 记录下原有的逆序对个数. 预处理出每个点取每个值所产生的逆序对个数,然后dp转移. #include<cstring> #inclu ...

  9. bzoj1786: [Ahoi2008]Pair 配对&&1831: [AHOI2008]逆序对

    一个自以为很对的东西,我们往-1放的数肯定是不增的. 然后就预处理一下,假如i这个位置放j会多多少逆序对. DP一下,我的复杂度应该是O(n*m^2)的,然而你随便搞都能省掉一个m吧,我算了算好像可以 ...

随机推荐

  1. Dropbox的可用Hosts文件

    108.160.167.203 www.dropbox.com 108.160.167.203 dropbox.com 108.160.165.211 dl-client677.dropbox.com ...

  2. 正确对待bug

    正确对待bug 2016-10-09 公众号:一只程序媛 以前我一直以为bug是代码的天敌,我以为好的程序媛写出来的代码是应该没有bug的,零bug是终极奋斗目标. 后来,看到一句话"上帝创 ...

  3. css为什么要用悬浮

    如果这个100px的宽度是一个Img,横内元素.右边也是横内元素的话和块级元素是不同的. 2.文字环绕图片. div下有个img然后有个span标签 img最好悬浮,悬浮虽然说脱离文档,但是还是占空间 ...

  4. 【BZOJ1006】【HNOI2008】神奇的国度(弦图染色)

    1006: [HNOI2008]神奇的国度 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 1467  Solved: 603[Submit][Stat ...

  5. 项目笔记---Socket Error Code翻译

    前言 在项目中为了方便调试及客户反馈,需要Socket错误数字的中文解释,MSDN上只有英文版,同时也想自己学习而且方便将来更新ErrorCode的实际发生的情景,顾有此博文. MSDN:https: ...

  6. 利用 NSSortDescriptor 对 NSMutableArray 排序

    有时我们在NSMutableArray中存的是网络请求返回的数据,而每一个元素又是一个NSDictionary,如果这时候需要把数组中的元素按照每个元素字典中某一个key来排序,那么我们可以利用Obj ...

  7. 一条命令使win7可以直接运行.net3.5程序

    dism /online /get-features 获取 功能名称 dism /online /enable-feature /featurename:NetFx3  启用win7自带的.net f ...

  8. git托管代码随笔--运用ssh传输,不用每次提交频繁输入github账号密码

    遇到问题:在使用git bash的时候 每次git push均要输入账号密码. 问题原因:使用的是http传输,需用ssh传输. 解决方法: 1.设置密钥 ssh-keygen -t rsa -C & ...

  9. Android的开发环境的发展演变

    1.Android的开发环境: 之前大家都是安装eclipse,然后再下载安装sdk等插件,还需要配置比较麻烦.不过2013年,有了新的选择,在I/O大会上,谷歌推出新的Android开发环境——An ...

  10. HTML5动画实例

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...