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 ...
随机推荐
- Amber
训练做的题里有板子单独拉出来. 欧拉筛 ],prim[N+]; int cnt; void Eular() { vis[]=vis[]=; ;i<N;i++) if(!vis[i]) { pri ...
- 跨域资源共享(CORS)-漏洞整理
绕过方法整理 绕过 - 仅对域名校验 #POC #"Access-Control-Allow-Origin: https://xx.co & Access-Control-Allow ...
- JavaScript搜索框响应事件
HTML页面,注意:不要使用form标签 <input type = "text" name="keyword" id="keyword&quo ...
- 记boost协程切换bug发现和分析
在分析了各大开源协程库实现后,最终选择参考boost.context的汇编实现,来写tbox的切换内核. 在这过程中,我对boost各个架构平台下的context切换,都进行了分析和测试. 在maco ...
- Angular 输入中的禁止特定输入值--Validator 与 Directive 实现
1 前言 最近在项目中涉及表单的情况下,需要对用户输入进行过滤,比如填写用户名的时候不可以使用空格或者特殊符号,这里有几个解决方法: 使用 Angular 的正则同步验证器 使用 RxJS对输入的值进 ...
- 标准标签库JSTL(JSP Standard Tag Library)
1, 核心标签(最常用, 最重要的) 表达式控制标签 out 输出常量 value---直接赋值 输出变量 default---默认值 escapeXml---控制转义字符(默认为true, 如果需要 ...
- Spring Security 01
环境搭建 maven依赖jar包 <!-- spring-security --> <dependency> <groupId>org.springframewor ...
- mybatis全局配置mybatis-config.xml
大部分时候,我们都是在Spring 里面去集成MyBatis.因为Spring 对MyBatis 的一些操作进行的封装,我们不能直接看到它的本质,所以先看下不使用容器的时候,也就是编程的方式,MyBa ...
- python——列表操作函数和方法
1.添加新元素 1.1 append()函数 描述:append() 方法用于在列表末尾添加新的对象. 语法:list.append(obj) 参数:obj -- 添加到列表末尾的对象. 返回值:该方 ...
- 70.Trapping Rain Water(容水量)
Level: Hard 题目描述: Given n non-negative integers representing an elevation map where the width of e ...