“科林明伦杯”哈尔滨理工大学第七届程序设计团队赛 G.Sorting(贪心,思路)
来源:互联网 发布:dvp14ss11ti编程手册 编辑:程序博客网 时间:2024/05/01 18:52
Description
You have an integer sequence a1 … an (integers are distinct) and you
need to sort it by ascending order. However, you can only swap two
integers at a time and the cost is (ai + aj) if you swap ai and aj.Your task is to calculate the minimum cost of sorting.
Input
There is an integer T on the first line, then T cases follow.
For each case, there is an integer n on the first line, and n integers
a1 … an on the second line.1 ≤ T ≤ 100
1 ≤ n ≤ 100000 (and 1 ≤ ∑n ≤ 1000000 for all test cases)
1 ≤ ai ≤ 109
Output
For each case, print the minimum cost on a single line.
Sample Input
533 2 148 1 2 451 8 9 7 668 4 5 3 2 79901343232 439583812 852399982 732257750 739673755 979883931 445261874 867592420 875627527
Sample Output
41741349324217281
思路
先说题意,给你一个序列,你可以任意交换两个数,每次交换两个数所花费的代价是这两个数的和,问最少需要花费多少代价可以使这个序列有序。
我继续转化成图论的方式来理解一下
我们以一组样例来说明:
51 8 9 7 6
首先对这个序列进行排序
我们从元素1开始看,排序后元素1的位置还是1,那么就给1到1之间连一条边,形成一个自环;再到元素8,元素8排序以后到了第4个位置,而第四个位置是元素7,所以给8到7之间连一条有向边,同理连完剩下的边可以得到一张图:
那么我们可以发现两个环,那么我们回到题目中来,要使最后的总和最小,我们的贪心思路是什么?
一:
对于每一个环的贪心思路就是,找到这个环中最小的那个点,也就是6,然后从6开始进行交换,6和9交换,可以使9到对应的位置,花费为6+9=15
,然后6和7交换,花费为6+7=13
,最后等到交换完毕,自最后的答案是什么呢?就是:
剩下一个环不用交换,那么当前的最小值就是42,但是这还不是最优解
二:
我们考虑,在这个图中找到一个最小的值,然后用这个值跟着当前的环进行交换,在这个图中很明显是1,我们让第1和第二个环中的最小值6进行交换,然后再像上面一样,交换1和9,花费为:1+9=10
,交换1和7,花费为:1+7=8
等到交换完毕,最后的结果是:
所以41比42小,显然41更优,所以我们的贪心策略就是在这两者之间,找出一个最小值
所以先用结构体存一下下标和值,然后用一个变量least记录一下整个序列中最小的,然后对于每个环,选择是用当前环中的最小值交换还是,整个序列的最小值进行交换,x存储当前环中点的个数,minn存储当前环中最小值,num算出当前环中的总和,最后求出这两种情况中最小的即可
代码
#include <cstdio>#include <cstring>#include <cctype>#include <stdlib.h>#include <string>#include <map>#include <iostream>#include <stack>#include <cmath>#include <queue>#include <vector>#include <algorithm>using namespace std;typedef long long ll;#define inf 0x3f3f3f3f#define mem(a,b) memset(a,b,sizeof(a))const ll N=100000+20;struct node{ ll pos; ll val;} a[N];bool cmp(node a,node b){ return a.val<b.val;}ll vis[N];ll least;ll solve(ll i){ ll j=a[i].pos; ll minn=a[i].val; vis[i]=1; ll x=0,num=a[i].val; while(!vis[j]) { num+=a[j].val; minn=min(minn,a[j].val); vis[j]=1; x++; j=a[j].pos; } return num+min(minn*(x-1),least*(x+2)+minn);}int main(){ ll n,x,t; scanf("%lld",&t); while(t--) { scanf("%lld",&n); mem(vis,0); for(ll i=1; i<=n; i++) { scanf("%lld",&a[i].val); a[i].pos=i; } sort(a+1,a+n+1,cmp); least=a[1].val; ll ans=0; for(ll i=1; i<=n; i++) { if(!vis[i]) { ans+=solve(i); } } printf("%lld\n",ans); } return 0;}
- “科林明伦杯”哈尔滨理工大学第七届程序设计团队赛 G.Sorting(贪心,思路)
- 科林明伦杯”哈尔滨理工大学第七届程序设计团队赛G
- 科林明伦杯哈尔滨理工大学第七届程序设计团队赛-水题*2
- 科林明伦杯哈尔滨理工大学第七届程序设计团队赛-Aggie’s Tasks
- “科林明伦杯”哈尔滨理工大学第七届程序设计团队赛 A. An Easy Geometry Problem(计算几何)
- “科林明伦杯”哈尔滨理工大学第七届程序设计团队赛 I.Aggie’s Tasks(带权的LIS)
- “科林明伦杯”哈尔滨理工大学第七届程序设计团队赛 I.Aggie’s Tasks(带权的LIS)
- "科林明伦杯"哈尔滨理工大学第六届程序设计团队赛
- "科林明伦杯"哈尔滨理工大学第六届程序设计团队赛(12.10)
- "科林明伦杯"哈尔滨理工大学第六届程序设计团队赛总结
- "科林明伦杯"哈尔滨理工大学第六届程序设计团队赛(流水账)
- "科林明伦杯"哈尔滨理工大学第六届程序设计团队赛 HRBUST 2315 Time(水)
- "科林明伦杯"哈尔滨理工大学第六届程序设计团队赛总结
- "尚学堂杯"哈尔滨理工大学第七届程序设计竞赛 G.Great Atm【贪心】
- "尚学堂杯"哈尔滨理工大学第七届程序设计竞赛 G(2331) Great Atm(二进制)(思路)
- 哈尔滨理工大学第七届程序设计竞赛(G.Great Atm)
- "尚学堂杯"哈尔滨理工大学第七届程序设计竞赛 D(2328).Distinct Package Manager(思路)
- 哈尔滨理工大学第六届程序设计团队赛G OX(博弈搜索)
- Python操作Mysql数据库
- 作业系列静态链表
- HOW2J——JAVA基础——控制流程综合练习
- Error:Execution failed for task ':xutils:mergeDebugAndroidTestResources'. > No slave process to proc
- Python练习——登录系统
- “科林明伦杯”哈尔滨理工大学第七届程序设计团队赛 G.Sorting(贪心,思路)
- Struts 2提交form表单执行action后不跳转(ajax)
- C++设计模式01——简单工厂模式
- 数组的定义和顺序实现
- 01爬虫---快速使用Urllib爬取网页
- 关于git连接github
- 送给前线码农的话
- 缓存命中
- Spring入门介绍