codeforces 584E Anton and Ira [想法题]
题意简述:
给定一个$1$到$n(n<=2000)$的初始排列以及最终排列 我们每次可以选取位置为$i$和$j$的
并交换它们的位置 花费为$ |i-j| $ 求从初始状态变换到末状态所需最小花费
-----------------------------------------------------------------------------------------------------------
比赛时这题留了$40min$ 然而自己贪心策略还是有漏洞
结束后看了首页的官方题解 感觉思路非常值得借鉴
首先 我们把末状态变为到$1~n $初状态也与之相对应地改变 (设为$a[i]$)
比如样例可以变为
$3 2 4 1$
$1 2 3 4$
我们假设每次交换花费为$ 2|i-j| $那么从初始状态到末状态最优的情况下花费即为
$\sum_{i}^{n}|a[i]-i|$
-----------------------------------------------------------------------------------------------------------
已经知道问题的下界了 我们再来考虑是否对于任意情况 总存在一种达到下界花费的方案
我们每次考虑当前状态中值最小且不在对应位置的数 然后找它左边第一个比它位置大的数
然后进行交换 直到它换到自己的目标位置
我们会发现 按照这样的换法 所有数都一直在向着目标位置移动 没有往返过
所以花费就是最小的 即 $\sum_{i}^{n}|a[i]-i|$
另外由于交换次数给的范围比较大 $(n^{2}/2)$ 刚好是比极限情况($n$到$1$排列)稍大
于是这题做到这里就可以解决了
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=;
int a[N],pos[N];
int ans1[N*N>>],ans2[N*N>>];
int n,k,ans;
int main()
{
scanf("%d",&n);
for(int i=;i<=n;++i)
scanf("%d",&a[i]);
int x;
for(int i=;i<=n;++i)
{
scanf("%d",&x);
pos[x]=i;
}
for(int i=;i<=n;++i)
a[i]=pos[a[i]];
for(int i=;i<=n;++i)
{
int j=i;
while(a[j]!=i)
++j;
while(j!=i)
{
int l=j-;
while(a[l]<j)
--l;
ans+=j-l;
++k;
ans1[k]=l;
ans2[k]=j;
swap(a[l],a[j]);
j=l;
}
}
printf("%d\n%d\n",ans,k);
for(int i=;i<=k;++i)
printf("%d %d\n",ans1[i],ans2[i]);
return ;
}
codeforces 584E Anton and Ira [想法题]的更多相关文章
- Codeforces 584E Anton and Ira
Anton and Ira 我们把点分为三类, 向左走的, 向右走的, 不动的. 最完美的情况就是每个点没有走反方向. 每次我们挑选最右边的向右走的去把向左走的交换过来,这样能保证最优. #inclu ...
- Codeforces 584E - Anton and Ira - [贪心]
题目链接:https://codeforces.com/contest/584/problem/E 题意: 给两个 $1 \sim n$ 的排列 $p,s$,交换 $p_i,p_j$ 两个元素需要花费 ...
- codeforces 657C - Bear and Contribution [想法题]
题目链接: http://codeforces.com/problemset/problem/657/C ----------------------------------------------- ...
- CodeForces - 156B Suspects 逻辑 线性 想法 题
题意:有1~N,n(1e5)个嫌疑人,有m个人说真话,每个人的陈述都形如X是凶手,或X不是凶手.现在给出n,m及n个陈述(以+x/-X表示)要求输出每个人说的话是true ,false or notd ...
- CodeForces - 798D Mike and distribution 想法题,数学证明
题意:给你两个数列a,b,你要输出k个下标,使得这些下标对应的a的和大于整个a数列的和的1/2.同时这些下标对应的b //题解:首先将条件换一种说法,就是要取floor(n/2)+1个数使得这些数大于 ...
- CodeForces - 55C Pie or die 想法题(猜程序)
http://codeforces.com/problemset/problem/55/C 题意:一个博弈. 题解:瞎猜,目前不清楚原理 #include<iostream> #inclu ...
- codeforces gym 100345I Segment Transformations [想法题]
题意简述 给定一个由A C G T四个字母组成的密码锁(每拨动一次 A变C C变G G变T T变A) 密码锁有n位 规定每次操作可以选取连续的一段拨动1~3次 问最少几次操作可以将初始状态变到末状态 ...
- codeforces 11 B.Jumping Jack 想法题
B. Jumping Jack Jack is working on his jumping skills recently. Currently he's located at point zero ...
- Codeforces Round #324 (Div. 2) E. Anton and Ira 贪心
E. Anton and Ira Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/584/probl ...
随机推荐
- Lambda拉姆达表达式
拉姆达表达式常用于委托,也就是说拉姆达表达式是匿名函数,简单点就是函数. a => a.Equals("string"); //原形为: (a) => { return ...
- hexo博客yilia主题深度设置
转载:Shuyan http://dongshuyan.com/2019/05/24/hexo博客注意事项/ 1.微信分享异常 这里是themes\yilia\layout\ _partial\pos ...
- python可变数据类型和不可变数据类型
1.可变数据类型:在id不变的情况下,value可改变(列表和字典是可变类型,但是字典中的key值必须是不可变类型) 2.不可变数据类型:value改变,id也跟着改变.(数字,字符串,布尔类型,都是 ...
- Oracle PL/SQL基础
1.下载sql developer数据库连接可视化工具 连接地址:点我下载 下载完成,安装有Java环境,解压即可运行,也可以在linux系统中运行.
- ubuntu下修改子网掩码
1.修改网络配置 修改 /etc/netplan/01-network-manager-all.yaml 文件 vi /etc/netplan/01-network-manager-all.yaml ...
- [转]ORACLE优化器RBO与CBO的区别
RBO和CBO的基本概念 Oracle数据库中的优化器又叫查询优化器(Query Optimizer).它是SQL分析和执行的优化工具,它负责生成.制定SQL的执行计划.Oracle的优化器有两种,基 ...
- JS面向对象——原型模型
以下通过一段示例代码,说明原型模型中的基本概念以及知识点. <!DOCTYPE html> <html> <head> <title>原型模型</ ...
- RabbitMQ基于Stomp实现与MQTT客户端通信
请参照RabbitMQ应用和SpringBoot集成RabbitMQ并实现消息确认机制 详情参照官方文档https://www.rabbitmq.com/stomp.html.https://gith ...
- CentOS 6.5之SSH 免密码登录
0.说明 这里为了方便说明问题,假设有A和B两台安装了centos6.5的主机.目标是实现A.B两台主机分别能够通过ssh免密码登录到对方主机.不同主机的配置过程一样,这里介绍A主机的配置过程. 事先 ...
- mysql的锁
前言 mysql锁的概念参考如下连接: 1.http://blog.csdn.net/u013063153/article/details/53432468 2.http://www.yesky.co ...