题意简述:

给定一个$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=2010;
int a[N],pos[N];
int ans1[N*N>>1],ans2[N*N>>1];
int n,k,ans;
int main()
{scanf("%d",&n);for(int i=1;i<=n;++i)scanf("%d",&a[i]);int x;for(int i=1;i<=n;++i){scanf("%d",&x);pos[x]=i;}for(int i=1;i<=n;++i)a[i]=pos[a[i]];for(int i=1;i<=n;++i){int j=i;while(a[j]!=i)++j;while(j!=i){int l=j-1;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=1;i<=k;++i)printf("%d %d\n",ans1[i],ans2[i]);return 0;
}

转载于:https://www.cnblogs.com/sagitta/p/4858692.html

codeforces 584E Anton and Ira [想法题]相关推荐

  1. Codeforces 584E. Anton and Ira (排列好题)

    大致题意: n <= 2000,有一1-n的排列p和s,对pi和pj交换产生的代价是 | i - j | , 问最少需要多少代价使,排列p变成排列s,输出解 思路: 可以先把s映射成1...n的 ...

  2. 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 ...

  3. codeforces#324(div2) E. Anton and Ira 贪心

    codeforces#324(div2) E. Anton and Ira  贪心 E. Anton and Ira time limit per test 1 second memory limit ...

  4. codeforces 324# E. Anton and Ira (暴力枚举+贪心)

    题目:http://codeforces.com/contest/584/problem/E 题意:给定两个排列p1和p2.可以交换p1中的两个元素p1[i],p1[j],花费为|i-j|,求最小的话 ...

  5. 51nod 1574 || Codeforces 584 E. Anton and Ira 思维+构造+贪心

    传送门:E. Anton and Ira 题意:给定两个1-n的全排列p和s,假设交换pi和pj的代价是abs(i-j),问怎样将p交换成s才能使代价最小. 思路:先将s映射成1-n的顺序排列,再将p ...

  6. Codeforces 1077B Disturbed People(思维题)

    Codeforces 1077B Disturbed People(思维题) There is a house with nn flats situated on the main street of ...

  7. [codeforces 1333A] Little Artem 读懂题+找规律+多举例

    Codeforces Round #632 (Div. 2)   比赛人数12810 [codeforces 1333A]   Little Artem   读懂题+找规律+多举例 总目录详见http ...

  8. 「想法题系列」逗比三角形-二分

    传送门:「想法题系列」逗比三角形-hzwer 题解 因为限制了盒子的宽,所以贪心让每个三角形尽量高(即让最短边紧贴盒子底面所在直线). 考虑把每个三角形竖着剖分成宽为 d d d的矩形. 将所有矩形降 ...

  9. Codeforces Round 700 (Div. 2) B题 英雄杀怪兽

    Codeforces Round 700 (Div. 2) B题 链接: https://codeforces.com/contest/1480/problem/B 大致意思: n组数据,每组数据的第 ...

  10. Codeforces Round #379 (Div. 2) A. Anton and Danik 水题

    A. Anton and Danik 题目连接: http://codeforces.com/contest/734/problem/A Description Anton likes to play ...

最新文章

  1. 全新的深度模型在推荐系统中的应用
  2. github创建项目_用了 GitHub 上这款开源神器后,创建项目文档变得 so easy!
  3. multi agent system university of liverpool professional presentation
  4. html不读取缓存,如何让前端浏览器不进行缓存
  5. ubuntu12.04 e680 usbnet
  6. :nth-child(n)与:nth-of-type(n)为啥显示不对呢
  7. C# OpenFileDialog 打开文件对话框 打开多文件对话框; 并获取其路径,文件名,扩展名/后缀名
  8. 《咏怀古迹五首·其三》.唐.杜甫
  9. java实现福利彩票抽奖_【福利】快来参与抽奖获得《Java程序设计》
  10. Android 6.0(棉花糖)新特性
  11. (27)python类的定义和使用
  12. 双下巴的瘦脸运动方法 - 健康程序员,至尚生活!
  13. C/C++语言ODBC连接SqlServer数据库
  14. Dijkstra 路径规划算法在二维仿真环境中的应用 -- Python代码实现
  15. Linux软件包安装
  16. PHP充值怎么打折,教大家如何用PHP语言写一个简单的商品打折小程序!
  17. uni-app提交表单成功之后跳转首页
  18. 记一次php、sql注入学习后的一道ctf代码审计题复盘
  19. idea下载源码失败 cannot download sources
  20. 集装箱货物装箱3D模型

热门文章

  1. 如何在Mac上的一个“预览”窗口中显示若干文件
  2. mac如何删除用户或者群组
  3. Screaming Frog SEO Spider for Mac进行网页抓取和数据提取的技巧
  4. 《程序员自我修养》阅读笔记-可执行文件装载与进程
  5. 前馈神经网络开山鼻祖---一些概念
  6. Excel中index和match函数的应用实例
  7. 深入浅出,解读阿里云云盾WAF防护功能
  8. BZOJ 2821 分块+二分
  9. Silverlight 1.0 beta 和1.1 Alpha体验
  10. IOS恢复备份使用帮助