传送门

题意

有 $ 2n $ 个球排成一行,其中恰好有 $ n $ 个白球和 $ n $ 个黑球。每个球上写着数字,其中白球上的数字的并集为 $ \lbrace 1 \dots n\rbrace $ ,黑球上的数字的并集也为 $ \lbrace 1 \dots n\rbrace $ 。

你可以交换任意两个相邻的球若干次,以使得对于所有白球,数字大小从左到右递增,黑球也是一样。

问你最少的交换次数。$ (n \leq 2000) $

题解

如果所有球最后的位置 $ P(i) $ 已经确定,那么最少交换次数 $ ans $ 为:

\[ans = \sum_{i=1}^{2n} \sum_{j=i+1}^{2n} [P(i) > P(j)]
\]

也就是相对位置改变了的球对 $ (i,j) $ 的个数。

然后考虑如何dp。

由于白球和黑球内部,数字大小递增,所以可以考虑从左到右依次填球。

$ dp[i][j] $ 表示已经从左到右填了 $ i $ 个白球,$ j $ 个黑球,此时的最小代价。

则最终答案就是 $ dp[n][n] $

然后考虑如何转移。

对于 $ dp[i][j] $ 来说,接下来要么填一个白球,要么填一个黑球。

设 $ costw[i][j] $ 表示已经填了 $ i $ 个白球,$ j $ 个黑球,该填第 $ i+1 $ 个白球,会增加的代价。

同理 $ costb[i][j] $ 表示已经填了 $ i $ 个白球,$ j $ 个黑球,该填第 $ j+1 $ 个黑球,会增加的代价。

则有转移:

\[dp[i][j] = min(dp[i-1][j]+costw[i-1][j],dp[i][j-1]+costb[i][j-1])
\]

边界条件为 $ dp[0][0] = 0 $

dp的复杂度为 $ O(n^2) $

对于 $ cost $ 数组来说,同样可以 $ O(n^2) $ 预处理。

首先可以 $ O(n^2) $ 暴力处理出所有 $ cost[i][0] $ 和 $ costb[0][j] $

设 $ P_w[i] $ 表示写着数字 $ i $ 的白球的初始位置,$ P_b[i] $ 表示写着数字 $ i $ 的黑球的初始位置。

则对于 $ cost $ 数组来说,有如下递推:

\[costw[i][j] = costw[i][j-1] + [P_b[j] > P_w[i+1]]
\]

\[costb[i][j] = costb[i-1][j] + [P_w[i] > P_b[j+1]]
\]

所以预处理总复杂度也是 $ O(n^2) $ 的。

AC Code

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #define MAX_N 2005
  5. using namespace std;
  6. int n;
  7. int pw[MAX_N];
  8. int pb[MAX_N];
  9. int dp[MAX_N][MAX_N];
  10. int costw[MAX_N][MAX_N];
  11. int costb[MAX_N][MAX_N];
  12. void read()
  13. {
  14. scanf("%d",&n);
  15. char s[4]; int x;
  16. for(int i=1;i<=(n<<1);i++)
  17. {
  18. scanf("%s%d",s,&x);
  19. if(s[0]=='W') pw[x]=i;
  20. else pb[x]=i;
  21. }
  22. }
  23. void cal_c()
  24. {
  25. for(int i=0;i<n;i++)
  26. {
  27. for(int j=1;j<=i;j++) costw[i][0]+=(pw[j]>pw[i+1]);
  28. for(int j=1;j<=n;j++) costw[i][j]=costw[i][j-1]+(pb[j]>pw[i+1]);
  29. }
  30. for(int j=0;j<n;j++)
  31. {
  32. for(int i=1;i<=j;i++) costb[0][j]+=(pb[i]>pb[j+1]);
  33. for(int i=1;i<=n;i++) costb[i][j]=costb[i-1][j]+(pw[i]>pb[j+1]);
  34. }
  35. }
  36. void cal_dp()
  37. {
  38. memset(dp,0x3f,sizeof(dp));
  39. dp[0][0]=0;
  40. for(int i=0;i<=n;i++)
  41. {
  42. for(int j=0;j<=n;j++)
  43. {
  44. if(i) dp[i][j]=min(dp[i][j],dp[i-1][j]+costw[i-1][j]);
  45. if(j) dp[i][j]=min(dp[i][j],dp[i][j-1]+costb[i][j-1]);
  46. }
  47. }
  48. }
  49. void work()
  50. {
  51. cal_c();
  52. cal_dp();
  53. printf("%d\n",dp[n][n]);
  54. }
  55. int main()
  56. {
  57. read();
  58. work();
  59. }

AtCoder ARC097C Sorted and Sorted:dp的更多相关文章

  1. arc 097 E - Sorted and Sorted

    E - Sorted and Sorted Time limit : 2sec / Memory limit : 1024MB Score : 600 points Problem Statement ...

  2. Atcoder D - 3N Numbers(优先队列+dp)

    题目链接:http://abc062.contest.atcoder.jp/tasks/arc074_b 题意:给出3*n个数要求去掉n个数使得剩下的前n个数-后n个数的差最大. 题解:显然是一道如果 ...

  3. AtCoder Beginner Contest 247 F - Cards // dp + 并查集

    原题链接:F - Cards (atcoder.jp) 题意: 给定N张牌,每张牌正反面各有一个数,所有牌的正面.反面分别构成大小为N的排列P,Q. 求有多少种摆放方式,使得N张牌朝上的数字构成一个1 ...

  4. UVa 10934 Dropping water balloons:dp(递推)

    题目链接:https://vjudge.net/problem/27377/origin 题意: 有一栋n层高的楼,并给你k个水球.在一定高度及以上将水球扔下,水球会摔破:在这个高度以下扔,水球不会摔 ...

  5. HDU 1028 Ignatius and the Princess III:dp or 母函数

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1028 题意: 给你一个正整数n,将n拆分成若干个正整数之和,问你有多少种方案. 注:"4 = ...

  6. Codeforces 893E Counting Arrays:dp + 线性筛 + 分解质因数 + 组合数结论

    题目链接:http://codeforces.com/problemset/problem/893/E 题意: 共q组数据(q <= 10^5),每组数据给定x,y(x,y <= 10^6 ...

  7. BZOJ 1677 [Usaco2005 Jan]Sumsets 求和:dp 无限背包 / 递推【2的幂次方之和】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1677 题意: 给定n(n <= 10^6),将n分解为2的幂次方之和,问你有多少种方 ...

  8. BZOJ 2023 [Usaco2005 Nov]Ant Counting 数蚂蚁:dp【前缀和优化】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2023 题意: 有n个家族,共m只蚂蚁(n <= 1000, m <= 1000 ...

  9. mine:dp

    一个小的线性dp.方法很多,八仙过海各显神通. 我想讲一下我的: #include<cstdio> #define mod 1000000007 ];][][],n;//是不是雷,右边有没 ...

随机推荐

  1. maven pom.xml常用标签 Exclusions plugins是什么意思

    Exclusions maven的依赖(dependencies)有传递性,为了解决兼容性问题,就用exclusions来排除造成兼容性问题的依赖. 写法如下: 加入项目A依赖项目B,项目B依赖项目C ...

  2. css 特殊处理样式记录

    1.解决任何盒子的垂直横向 居中显示 display: -webkit-box; -webkit-flex: 1; -webkit-box-orient: vertical; -webkit-box- ...

  3. openssl update--centos 6.5

    cd /usr/local/src #wget http://www.openssl.org/source/openssl-1.0.1h.tar.gz #tar -zxvf openssl-1.0.1 ...

  4. <2014 05 21> 互联网时代的C语言——Go

    Go希望成为互联网时代的C语言. 多数系统级语言(包括Java和C#)的根本编程哲学来源于C++,将C++的面向对象进一步发扬光大.但是Go语言的设计者却有不同的看法,他们认为C++ 真的没啥好学的, ...

  5. 序列化组件之生成hypermedialink

    一  生成hypermedialink(极少数) 组件 class BooksSerializer(serializers.ModelSerializer): name = serializers.C ...

  6. JVM虚拟机—JVM的类加载机制

    1 什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构 ...

  7. 基于mondrain 的原理纠正特殊指标值

    原文地址:http://www.cnblogs.com/qiaoyihang/p/7348385.html 下面有两张表 数学试卷成绩 表1 学号 省份 批次 学校 试卷成绩 数学试卷小题成绩 表2 ...

  8. 初识ambari

    本文地址:http://www.cnblogs.com/qiaoyihang/p/6290467.html 引用:http://blog.csdn.net/yeruby/article/details ...

  9. Hadoop的IO操作

    Hadoop的API官网:http://hadoop.apache.org/common/docs/current/api/index.html   相关的包 org.apache.hadoop.io ...

  10. sersync的confxml.xml文件详解

    <?xml version="1.0" encoding="ISO-8859-1"?> <head version="2.5&quo ...