[洛谷P2127] 序列排序
洛谷题目链接:序列排序
题目描述
小C有一个N个数的整数序列,这个序列的中的数两两不同。小C每次可以交换序列中的任意两个数,代价为这两个数之和。小C希望将整个序列升序排序,问小C需要的最小代价是多少?
输入输出格式
输入格式:
第一行,一个整数N。
第二行,N个整数,表示小C的序列。
输出格式:
一行,一个整数,表示小C需要的最小代价。
输入输出样例
输入样例#1:
6
8 4 5 3 2 7
输出样例#1:
34
说明
数据范围:
对于30%的数据,1<=N<=10;
对于全部的数据,1<=N<=100000,输入数据中的其他整数均为正整数且不超过109。
简述一下题意:给出一个长度为n的序列(其中元素权值各不相同),通过多次交换两个元素使得整个序列为升序.每次交换的代价是交换的两个元素的权值,要求出最小的代价.
简单想一下,因为每个权值都不同,那么很显然我们是知道最终状态是怎么样的,那么很显然不论怎么样交换,每个元素都有一个它最终要到的位置.
既然这样,那么我们可以处理出每个元素最终要到的位置,以这样方式交换那么序列中的交换情况就可以看作是几个环.
现在假设有这样一个序列:3 1 2 5 4.它的最优交换方法为swap(1 , 2),swap(1 , 3),swap(4 , 5).1要到第一位,2要到第2位,3要到第3位,很显然1,2,3这三个下标上的数组成了一个交换的环,也就是从一个位置出发一直找该下标元素最终要到的位置,然后再从这个位置出发直到走到一开始出发的那个位置.(我们接下来讲的环都是指这个概念),那么在环上交换的贪心策略很显然是用最小的值与其他值来交换.
那么显然可以得到这样一个贪心:
找到一个交换的环中最小的权值,用它来与在这个环上的其他未归位的元素交换.
但是这样的贪心仍然是有问题的.我们看这样一组数据:
5
1 60 30 40 50
如果只考虑用换上的最小值来交换的话,求出来的答案是240,但是如果先将环上最小值和整个序列上的最小值进行交换,然后用这个最小值来代替之前的最小值来计算,就有可能得到更优解.
于是得到一个优化后的贪心策略:判断是使用当前交换环上最小值来完成交换还是先将环上最小值与整个序列最小值交换得到的结果更优.
然后就是注意一下找环的时候一些边界问题,注意一下细节就没了.
#include<bits/stdc++.h>
using namespace std;
typedef long long lol;
const int N=100000+5;
const int inf=2147483647;
lol n, ans = 0, w[N];
lol len = 0, tot = 0;
lol mn = inf, minn = inf;
struct brick{
lol id, w;
}a[N];
bool cmp(brick a,brick b){
return a.w < b.w;
}
int main(){
cin >> n;
for(lol i=1;i<=n;i++){
cin >> a[i].w;
a[i].id = i; w[i] = a[i].w;
minn = min(minn , a[i].w);
}
sort(a+1 , a+n+1 , cmp);
for(lol i=1;i<=n;i++){
if(a[i].id != i){
lol k = a[i].id; tot = w[i]; len = 1;
a[i].id = i; mn = w[i];
while(k!=i){//找环
len++; mn = min(mn , w[k]);
tot += w[k];
swap(a[k].id , k);
}
if(mn == minn) ans += tot+mn*(len-2);
else ans += min(minn*(len+1)+mn+tot,tot+mn*(len-2));//判断哪种情况更优
}
}
cout << ans << endl;
return 0;
}
[洛谷P2127] 序列排序的更多相关文章
- 洛谷 P2127 序列排序
https://www.luogu.org/problemnew/show/P2127 感觉题解里写的比较复杂,可能自己的想法比较简单一点吧. 看这个图中的的点如果形成一个环,贪心的考虑,要想花费最少 ...
- 洛谷P2127 序列排序 [贪心]
题目传送门 题目描述 小C有一个N个数的整数序列,这个序列的中的数两两不同.小C每次可以交换序列中的任意两个数,代价为这两个数之和.小C希望将整个序列升序排序,问小C需要的最小代价是多少? 输入输出格 ...
- 洛谷 P4597 序列sequence 解题报告
P4597 序列sequence 题目背景 原题\(\tt{cf13c}\)数据加强版 题目描述 给定一个序列,每次操作可以把某个数\(+1\)或\(-1\).要求把序列变成非降数列.而且要求修改后的 ...
- 洛谷P4891 序列 || 膜法阵,魔法阵
https://www.luogu.org/problemnew/show/P4891 一道几乎一样的题http://210.33.19.103/contest/1130/problem/3 题面ht ...
- 洛谷P4891 序列(势能线段树)
洛谷题目传送门 闲话 考场上一眼看出这是个毒瘤线段树准备杠题,发现实在太难调了,被各路神犇虐哭qwq 考后看到各种优雅的暴力AC......宝宝心里苦qwq 思路分析 题面里面是一堆乱七八糟的限制和性 ...
- 【洛谷P2127】序列排序
题目大意:给定一个长度为 N 的序列,序列中的数两两不相同,每次可以交换序列中任意两个数,代价为这两个数的和,问将序列调整为升序,最少的代价是多少. 题解:考虑这个问题的一个子问题,这个序列为 N 的 ...
- P2127 序列排序
题目描述 小C有一个N个数的整数序列,这个序列的中的数两两不同.小C每次可以交换序列中的任意两个数,代价为这两个数之和.小C希望将整个序列升序排序,问小C需要的最小代价是多少? 输入输出格式 输入格式 ...
- [UVA1402]Robotic Sort;[SP2059]CERC07S - Robotic Sort([洛谷P3165][CQOI2014]排序机械臂;[洛谷P4402][Cerc2007]robotic sort 机械排序)
题目大意:一串数字,使用如下方式排序: 先找到最小的数的位置$P_1$,将区间$[1,P_1]$反转,再找到第二小的数的位置$P_2$,将区间$[2,P_2]$反转,知道排序完成.输出每次操作的$P_ ...
- 洛谷2085最小函数值(minval) + 洛谷1631序列合并
题目描述 有n个函数,分别为F1,F2,-,Fn.定义Fi(x)=Ai*x^2+Bi*x+Ci (x∈N*).给定这些Ai.Bi和Ci,请求出所有函数的所有函数值中最小的m个(如有重复的要输出多个). ...
随机推荐
- 设计模式——模版方法模式详解(论沉迷LOL对学生的危害)
. 实例介绍 在本例中,我们使用一个常见的场景,我们每个人都上了很多年学,中学大学硕士,有的人天生就是个天才,中学毕业就会微积分,因此得了诺贝尔数学奖:也有的人在大学里学了很多东西,过得很充实很满意 ...
- Mysql综合练习作业50题
#作业库create database db8 charset utf8; #年级表create table class_grade(gid int not null primary key auto ...
- elasticsearch 关联查询
父-子关系文档 父-子关系文档 在实质上类似于 nested model :允许将一个对象实体和另外一个对象实体关联起来. 而这两种类型的主要区别是:在 nested objects 文档中,所有对象 ...
- spring、spring-data-redis整合使用
一.Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. 从2010年3月15日起,Redis的开发工作由VMwa ...
- 06-Mysql数据库----表的操作
06-表的操作 本节掌握 存储引擎介绍(了解) 表的增删改查 一.存储引擎(了解) 前几节我们知道mysql中建立的库===>文件夹,库中的表====>文件 现实生活中我们用来存储数据 ...
- PHP实现字节数Byte转换为KB、MB、GB、TB
function getFilesize($num) { $p = 0; $format = 'bytes'; if( $num > 0 && $num < 1024 ) ...
- JVM 什么时候会触发FGC
1:System.gc(); 2:老年代满了 没啥好说的从年轻代去往老年代的 3:JDK7或JDK6中永久区满了 得看是否还会有分配,如果没有就不会进行FGC,不过CMS GC下会看到不停地CMS G ...
- 剑指offer-树的子结构17
题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) class Solution: def issubTree(self,pRoot1,pRoot2) ...
- FFT的物理意义(转载)
文章转载自: http://blog.sina.com.cn/s/blog_640029b301010xkv.html FFT是离散傅立叶变换的快速算法,可以将一个信号变换到频域.有些信号在时域上是很 ...
- eclipse快捷键(复制自己看)
1几个最重要的快捷键 代码助手:Ctrl+Space(简体中文操作系统是Alt+/)快速修正:Ctrl+1单词补全:Alt+/打开外部Java文档:Shift+F2 显示搜索对话框:Ctrl+H快速O ...