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 ...
随机推荐
- VS2017使用assimp 5.0.0 error C2589: '(' : illegal token on right side of '::' 解决办法
坑爹微软Sucks Again. assimp 终于更新到了5.0.0并且支持GLTF2格式,包含动画正确解析,在viewer中也能看到正确结果,真他喵的不容易,然后拿来编译完到自己项目里用,就出这玩 ...
- DataContract] [DataMember] 程序集引用
引用,右键->添加引用->System.Runtime.Serialization 添加
- html+css+js实现简单登陆注册页面
先看一下最终效果,登陆和注册 背景图片: 附源码: login.html <!DOCTYPE html> <html lang="en"> <head ...
- String.prototype.includes
if (!String.prototype.includes) { String.prototype.includes = function(search, start) { 'use s ...
- js提交map类型参数
方式一:使用 xmlHttpRequest 对象发送数据 function sendMapPost(map, url){ var xmlHttpRequest = createXMLHttpReque ...
- P3806 【模板】点分治1(题解)(点分治)
P3806 [模板]点分治1(题解)(点分治) 洛谷题目传送门 #include<iostream> #include<cstdlib> #include<cstdio& ...
- 从0构建webpack开发环境(二) 添加css,img的模块化支持
在一个简单的webpack.config.js中,构建了一个基础的webpack.config.js文件,但是只支持js模块的打包. 本篇中添加对css和img的模块化支持 首先需要安装三个个load ...
- Codecraft-17 and Codeforces Round #391 - C
题目链接:http://codeforces.com/contest/757/problem/C 题意:给定n个gym和m个Pokemon的类型,然后给你每个gym内的Pokemon未进化之前的类型, ...
- 广义Fibonacci数列找循环节 学习笔记
遇到了2019ICPC南昌赛区的网络赛的一道题,fn=3*fn-1+2*fn-2,有多次询问求fn.总结起来其实就是在模P意义下,O(1)回答广义斐波那契额数列的第n项,可以说是一道模板题了. 这道题 ...
- pip安装依赖包
pip install -r requirements.txt setup.py 模块使用 https://blog.csdn.net/neil_pan/article/details/7900129 ...