AtCoder ARC097C Sorted and Sorted:dp
题意
有 $ 2n $ 个球排成一行,其中恰好有 $ n $ 个白球和 $ n $ 个黑球。每个球上写着数字,其中白球上的数字的并集为 $ \lbrace 1 \dots n\rbrace $ ,黑球上的数字的并集也为 $ \lbrace 1 \dots n\rbrace $ 。
你可以交换任意两个相邻的球若干次,以使得对于所有白球,数字大小从左到右递增,黑球也是一样。
问你最少的交换次数。$ (n \leq 2000) $
题解
如果所有球最后的位置 $ P(i) $ 已经确定,那么最少交换次数 $ ans $ 为:
\]
也就是相对位置改变了的球对 $ (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[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 $ 数组来说,有如下递推:
\]
\]
所以预处理总复杂度也是 $ O(n^2) $ 的。
AC Code
#include <iostream>
#include <stdio.h>
#include <string.h>
#define MAX_N 2005
using namespace std;
int n;
int pw[MAX_N];
int pb[MAX_N];
int dp[MAX_N][MAX_N];
int costw[MAX_N][MAX_N];
int costb[MAX_N][MAX_N];
void read()
{
scanf("%d",&n);
char s[4]; int x;
for(int i=1;i<=(n<<1);i++)
{
scanf("%s%d",s,&x);
if(s[0]=='W') pw[x]=i;
else pb[x]=i;
}
}
void cal_c()
{
for(int i=0;i<n;i++)
{
for(int j=1;j<=i;j++) costw[i][0]+=(pw[j]>pw[i+1]);
for(int j=1;j<=n;j++) costw[i][j]=costw[i][j-1]+(pb[j]>pw[i+1]);
}
for(int j=0;j<n;j++)
{
for(int i=1;i<=j;i++) costb[0][j]+=(pb[i]>pb[j+1]);
for(int i=1;i<=n;i++) costb[i][j]=costb[i-1][j]+(pw[i]>pb[j+1]);
}
}
void cal_dp()
{
memset(dp,0x3f,sizeof(dp));
dp[0][0]=0;
for(int i=0;i<=n;i++)
{
for(int j=0;j<=n;j++)
{
if(i) dp[i][j]=min(dp[i][j],dp[i-1][j]+costw[i-1][j]);
if(j) dp[i][j]=min(dp[i][j],dp[i][j-1]+costb[i][j-1]);
}
}
}
void work()
{
cal_c();
cal_dp();
printf("%d\n",dp[n][n]);
}
int main()
{
read();
work();
}
AtCoder ARC097C Sorted and Sorted:dp的更多相关文章
- arc 097 E - Sorted and Sorted
E - Sorted and Sorted Time limit : 2sec / Memory limit : 1024MB Score : 600 points Problem Statement ...
- Atcoder D - 3N Numbers(优先队列+dp)
题目链接:http://abc062.contest.atcoder.jp/tasks/arc074_b 题意:给出3*n个数要求去掉n个数使得剩下的前n个数-后n个数的差最大. 题解:显然是一道如果 ...
- AtCoder Beginner Contest 247 F - Cards // dp + 并查集
原题链接:F - Cards (atcoder.jp) 题意: 给定N张牌,每张牌正反面各有一个数,所有牌的正面.反面分别构成大小为N的排列P,Q. 求有多少种摆放方式,使得N张牌朝上的数字构成一个1 ...
- UVa 10934 Dropping water balloons:dp(递推)
题目链接:https://vjudge.net/problem/27377/origin 题意: 有一栋n层高的楼,并给你k个水球.在一定高度及以上将水球扔下,水球会摔破:在这个高度以下扔,水球不会摔 ...
- HDU 1028 Ignatius and the Princess III:dp or 母函数
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1028 题意: 给你一个正整数n,将n拆分成若干个正整数之和,问你有多少种方案. 注:"4 = ...
- Codeforces 893E Counting Arrays:dp + 线性筛 + 分解质因数 + 组合数结论
题目链接:http://codeforces.com/problemset/problem/893/E 题意: 共q组数据(q <= 10^5),每组数据给定x,y(x,y <= 10^6 ...
- BZOJ 1677 [Usaco2005 Jan]Sumsets 求和:dp 无限背包 / 递推【2的幂次方之和】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1677 题意: 给定n(n <= 10^6),将n分解为2的幂次方之和,问你有多少种方 ...
- BZOJ 2023 [Usaco2005 Nov]Ant Counting 数蚂蚁:dp【前缀和优化】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2023 题意: 有n个家族,共m只蚂蚁(n <= 1000, m <= 1000 ...
- mine:dp
一个小的线性dp.方法很多,八仙过海各显神通. 我想讲一下我的: #include<cstdio> #define mod 1000000007 ];][][],n;//是不是雷,右边有没 ...
随机推荐
- 巨蟒python全栈开发-第8天 文件操作
一.文件操作 今日大纲: 1.文件操作->open() open 打开 f=open(文件路径,mode='模式',encoding='编码格式') #python最最底层操作的就是bytes ...
- 巨蟒python全栈开发-第20天 核能来袭-约束 异常处理 MD5 日志处理
一.今日主要内容 1.类的约束(对下面人的代码进行限制;项目经理的必备技能,要想走的长远) (1)写一个父类,父类中的某个方法要抛出一个异常 NotImplementedError(重点) (2)抽象 ...
- 设计4个线程,其中2个对num进行加操作,另两个对num进行减操作
/** * 设计4个线程,其中2个对num进行加操作,另两个对num进行减操作 */ public class ThreadTest { private int j; public static vo ...
- 阻塞IO 非阻塞IO 异步IO
阻塞IO 一般表现为 进程/线程 调用IO操作后就一直死循环等待,直至IO操作结束,返回IO结果 非阻塞IO 一般表现为 进程/线程 调用IO操作后,可以先去干别的事情,但是每隔一段时间,回去询问一下 ...
- CSDN编程挑战——《进制转换》
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/user_longling/article/details/24804949 进制转换 题目详情: 我 ...
- android studio 中类似VS的代码折叠功能Region
1. 打开android studio 2. 选择要折叠的代码 3. 按Ctrl + Alt + T 选择 “region .. end region comments” Group selectio ...
- Hurst指数以及MF-DFA
转:https://uqer.io/home/ https://uqer.io/community/share/564c3bc2f9f06c4446b48393 写在前面 9月的时候说想把arch包加 ...
- Excel数据常用操作,vlookup,text,trim,数据格式导致出错
数据有缺漏,需要在数据前面补零 =TEXT(F70,"000000") 前面是要操作的数据,后面是补几位 匹配数据(将一个表格中的数据进行匹配) =VLOOKUP(C2,aaa,4 ...
- Python(面向对象编程——2 继承、派生、组合、抽象类)
继承与派生 ''' 继承:属于 组合:包含 一. 在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称 ...
- linux网络基础设置 以及 软件安装
ifconfig #查看所有已激活的网卡信息 临时配置 #yum install net-tools -y 默认ifconfig是没有安装的,可能需要安装 ifconfig eth0 #查看单独一块网 ...