2845 排序的代价

2845 排序的代价

时间限制: 1 s

空间限制: 32000 KB

题目等级 : 黄金 Gold

题解

题目描述 Description

有一列数,要对其进行排序(升序)。排序只能通过交换来实现。每次交换,可以选择这列数中的任意二个,交换他们的位置,并且交换的代价为二个数的和。排序的总代价是排序过程中所有交换代价之和。先要求计算,对于任意给出的数列,要将其排成升序所需的最小代价。

输入描述 Input Description

输入数据有两行组成。第一行一个数n,表示这列数共有n个数组成,第二行n个互不相同的整数(都是小于1000的正整数),表示这列数

输入可能包含多组测试数据(少于50组),对于每个输入数据均需要给出对应的输出

输出描述 Output Description

对于每个输入数据,输出最小代价。格式为Case t: min

其中t为数据的编号,从1开始,min为这个数据的最小代价

样例输入 Sample Input

3

3 2 1

4

8 1 2 4

样例输出 Sample Output

Case 1: 4

Case 2: 17

数据范围及提示 Data Size & Hint

n<=1000

分类标签 Tags 点此展开

置换群 群论

题解:

置换群+离散化.

使一个数列恢复递增顺序,那么,他和他要到达的位置的数需要交换,这样就形成了一个置换.

对于一个有向圈的置换,我们可以证明它的最小代价就是这个有向圈中 最小元素*(有向圈的大小-1)+其他数的和-最小元素.

1个大小为n的有向环,至少会进行n-1次交换才能成为n个1元环

当size=1,2 时,它显然成立.
当size>2 时,每次交换1个元素会将圆圈拆成两个互不相交的置换,一直拆下去需要拆n-1次.

然后还有一个问题就是我们可以把一个最小的数拉过来进行交换,这样我们就需要的代价就是,用最小的和有向圈中最小的交换,再让最小的*(有向圈大小-1)

这样这道题就显而易见了,至于不是连续的,我们可以离散化.

AC代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e3+10;
int n,cnt,ans,cas;
int r[N],a[N],b[N],c[N],s1;
int p[N][N],s[N],h[N];
bool vis[N];
int main(){
    while(scanf("%d",&n)==1){
        cnt=ans=0;
        memset(vis,0,sizeof vis);
        memset(p,0,sizeof p);
        memset(h,0,sizeof h);
        for(int i=1;i<=n;i++) scanf("%d",r+i);
        for(int i=1;i<=n;i++) a[i]=r[i];
        sort(a+1,a+n+1);s1=a[1];
        for(int i=1;i<=n;i++) b[a[i]]=i;
        for(int i=1;i<=n;i++) c[i]=b[r[i]];
        for(int i=1,t;i<=n;i++) if(!vis[i]){
            s[++cnt]=r[t=i];
            while(!vis[t]) vis[t]=1,p[cnt][++p[cnt][0]]=r[t],s[cnt]=min(s[cnt],r[t]),h[cnt]+=r[t],t=c[t];
        }
        for(int i=1;i<=cnt;i++){
            ans+=min(s[i]*(p[i][0]-1)+h[i]-s[i],s[i]*2+s1*2+s1*(p[i][0]-1)+h[i]-s[i]);
        }
        if(!ans) break;
        printf("Case %d: %d\n",++cas,ans);
    }
    return 0;
}
时间: 2024-10-06 21:27:13

2845 排序的代价的相关文章

CodeVS 2845 排序的代价

Description 给你一个数列使他递增,交换两个元素的代价为两个数的和,最小化代价. Sol 置换群+离散化. 使一个数列恢复递增顺序,那么,他和他要到达的位置的数需要交换,这样就形成了一个置换. 对于一个有向圈的置换,我们可以证明它的最小代价就是这个有向圈中 最小元素*(有向圈的大小-1)+其他数的和-最小元素. 1个大小为n的有向环,至少会进行n-1次交换才能成为n个1元环 当 \(size=1,2\) 时,它显然成立. 当 \(size>2\) 时,每次交换1个元素会将圆圈拆成两个互

排序的代价

[题目描述] 有一列数,要对其进行升序排序.排序只能通过交换来实现.每次交换,可以选择这列数中的任意两个,交换他们的位置,并且交换的代价为两个数的和.排序的总代价是排序过程中所有交换代价之和.现要求计算,对于给出的数列,要将其排成升序所需的最小代价. [输入描述] 第一行输入1个数n,表示这列数共有n(n <= 1000)个数组成: 第二行输入n个互不相同的整数(都是小于1000的正整数),表示这列数. 输入可能包含多组测试数据(少于50组),对于每个输入数据均需要给出对应的输出. [输出描述]

【转载】Alpha混合物体的深度排序

原文:Alpha混合物体的深度排序 先说个题外话, 本来我想解答一下最近Creators Club论坛上经常出现的一个问题, 意外的是在网上竟然找不到什么全面的答案.. 这是个有着复杂答案的简单问题: “为什么我的透明物体的绘制顺序不对, 或者有些不见了?” 当绘制一个3D场景时, 对图形进行深度排序是非常重要的, 这样离镜头近才画在远处物体的前面. 我们不会希望看到远处的山把近在眼前的建筑给挡住了! 如今有三种深度排序方法得到了广泛的应用: 深度缓冲 (也叫做 z-buffering) 油画家

贪心+拓扑排序 AOJ 2456 Usoperanto

题目传送门 题意:给出一条链,比如x连到y,x一定要在y的左边,且代价是这条链经过的点的权值和,问如何排序使得代价最小 分析:类似拓扑排序,先把入度为0的点入队,把指向该点的所有点按照权值排序,保证这样是代价是最小的,然后把这一块看成一个点继续入队.看图更简单: /************************************************ * Author :Running_Time * Created Time :2015/10/3 星期六 13:02:41 * File

深度排序与alpha混合 【转】

  翻译:李现民 最后修改:2012-07-03 原文:Depth sorting alpha blended objects 先说个题外话,本来我想回答在 Creators Club论坛上的一个常见问题,但(意外的是)我竟然没能从网上找到一个令人满意的答案. 问题本身很简单,但答案却有些复杂: “为什么我的透明物体的绘制顺序是错误的,或者为什么它们的一部分不见了?” 当绘制一个3D场景的时候,将图形按深度排序非常重要,只有这样靠近摄像机的物体才能被绘制在(离摄像机)更远的物体的上面.我们不会希

算法导论——lec 08 线性时间排序

之前我们介绍了几种O(nlgn)的排序算法:快速排序.合并排序和堆排序,本节我们介绍基于比较的排序算法的下界以及几个线性时间的排序算法--计数排序.基数排序.桶排序. 一. 比较排序算法的下界 1. 决策树模型:比较排序可以被抽象的视为决策树.一棵决策树是一棵满二叉树,表示某排序算法 作用于给定输入所做的所有比较. 排序算法的执行对应于遍历一条从树的根到叶结点的路径.在每个内节结点处要做比较. 要使排序算法能正确的工作,其必要条件是,n 个元素的n!种排列中的每一种都要作为决策树 的一个叶子而出

深度排序与alpha混合

原文: https://blogs.msdn.microsoft.com/shawnhar/2009/02/18/depth-sorting-alpha-blended-objects/ 翻译:李现民 最后修改:2012-07-03 "为什么我的透明物体的绘制顺序是错误的,或者为什么它们的一部分不见了?" 当绘制一个3D场景的时候,将图形按深度排序非常重要,只有这样靠近摄像机的物体才能被绘制在(离摄像机)更远的物体的上面.我们不会希望远方的山脉被绘制在近在眼前的建筑物的上面! 当前得到

BZOJ1119: [POI2009]SLO

1119: [POI2009]SLO Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 379  Solved: 181[Submit][Status] Description 对于一个1-N的排列(ai),每次你可以交换两个数ax与ay(x<>y),代价为W(ax)+W(ay) 若干次交换的代价为每次交换的代价之和.请问将(ai)变为(bi)所需的最小代价是多少. Input 第一行N. 第二行N个数表示wi. 第三行N个数表示ai. 第四行N个

sort的入门级notes

段首依旧复制 嗯,受人所托,顺便整理的 英文渣 侵删. // 注释的部分是解说(废话)和不怎么重(kǎo)要(chá)的 错误请指正 大晚上的先写原理 //冒泡排序 冒泡是对此排序形象的比喻…… 甚至非相关专业的同学也能对这种排序有十分直观的认识 大概就是数越大,代表的泡泡越大,浮力越大,当与其他较小的泡泡相遇时,更容易浮上去 结果序列便是按“浮力”大小排序的了 //插入排序 divide and conquer 大体思想是在已经有序的序列里插入新元素 //桶排序 对于uint来说,桶排序的段长