uva 1016 - Silly Sort(置换的灵活应用)
来源:互联网 发布:java 统计一年月消费 编辑:程序博客网 时间:2024/06/04 23:28
题意:给你n个不同数,可以进行一种操作,交换任意两个数的位置,则花费为两数的和,求把原序列变为严格单调递增的序列的最小花费
解析:通过置换可以发现原序列可以分为多个周期(循环)的变换,如8 4 5 3 2 7 变为(8 2 7)和(4 3 5),对于每个周期,所有数都不在他升序后的位置,即所有的数都需要交换,每次用周期内最小的数与另一个数交换,设这个周期的最小值为min,数量为size,所有数的和为sum ,则易得最小花费为min*(size-1)+sum-min,这样得到的花费就是最小值了
但需注意的是在进行变换时,我们可以先把 所有数的最小值Min 和min先交换,当这个周期成升序后再交换回来,则花费为2*(min+Min)+sum-min+(size-1)*Min 比较两者最小值即答案
//保存周期
#include<iostream>#include<cstdio>#include<math.h>#include<string.h>#include<algorithm>#include<vector>using namespace std;#define N 10005int k,n,a[N],c[N],b[N],vis[N],minx;long long res;vector<int> w[N];void inint(){ int i,j; minx=N*2; for(i=0;i<N;i++) w[i].clear(); for(i=0; i<n; i++) { scanf("%d",&a[i]); c[i]=a[i]; } sort(c,c+n); minx=c[0]; for(i=n-1; i>=0; i--) { b[c[i]]=a[i]; } memset(vis,0,sizeof(vis)); for(i=0; i<n; i++) { j=c[i]; while(!vis[j]) { vis[j]=1; w[k].push_back(j); j=b[j]; } k++; }}int main(){ // freopen("in.txt","r",stdin); // freopen("outw.txt","w",stdout); int i,j,s,min,qq=0,t=0; while(~scanf("%d",&n)&&n) { res=k=0; inint(); for(i=0; i<k; i++) { s=w[i].size(); if(s<=1) continue; min=2*N; for(j=0;j<s;j++) { res+=w[i][j]; if(w[i][j]<min) min=w[i][j]; } res-=min; if(min!=minx&&min*(s-1)>(s+1)*minx+2*min) res+=(s+1)*minx+2*min; else res+=(s-1)*min; } t++; // if(t>=2) puts(""); printf("Case %d: %lld\n\n",t,res); } return 0;}
//直接求答案 快些
#include <iostream>#include <cstdio>#include <map>#include <algorithm>using namespace std;int a[100000];int b[100000];bool vis[100000];int main (void){ // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int N; int t = 0; while (~scanf("%d", &N) && N) { t++; for (int i = 0; i < N; ++i) { scanf("%d", &a[i]); b[i] = a[i]; vis[i] = false; } sort(b, b + N); // Map the numbers to their desired place after sort map<int, int> place; for (int i = 0; i < N; ++i) { place[b[i]] = i; } int res = 0; for (int i = 0; i < N; ++i) { if (vis[i] == false) { if (place[a[i]] == i) { vis[i] = true; continue; } // We're in new cycle int min_val = a[i]; int num = 0; int sum = 0; int j = i; while (vis[j] == false) { sum += a[j]; num++; if (a[j] < min_val) { min_val = a[j]; } vis[j] = true; j = place[a[j]]; } sum -= min_val; res += sum ; // Let's try to borrow the minimum value. // If it's less costly then update our result. if (2 * (b[0] + min_val) <(min_val - b[0]) * (num - 1)) { res += ( b[0]) * (num - 1) +2 * (b[0] + min_val); } else res+=(num-1)*min_val; } } printf("Case %d: %d\n\n", t, res); } return 0;}
- uva 1016 - Silly Sort(置换的灵活应用)
- UVA 1016 - Silly Sort(置换分解+贪心)
- uva 1016 - Silly Sort(置换+贪心)
- UVA 1016 - Silly Sort
- Silly Sort
- 数组的灵活应用
- 置换 置换群 应用
- 置换 置换群 应用
- 置换 置换群 应用
- 编写灵活的RMS应用
- 专业在生活中的灵活应用
- 二分查找的灵活应用
- HTML九九乘法表的灵活应用
- poj 3270 Cow Sort(置换群的分解)
- 置换 置换群 应用 +置换群对某些算法问题的解释
- uva 10601 - Cubes(置换)
- uva 11255 - Necklace(置换)
- sort的应用
- ORACLE 使用RMAN管理归档日志 archived log
- unityd 模型跟随鼠标移动,鼠标隐藏
- iOS -- @property属性说明
- Win7+PHP 5.4.19+Apache 2.2+phpMyAdmin 4.0
- android启动过程分析--启动systemServer
- uva 1016 - Silly Sort(置换的灵活应用)
- cassandra中遇到的问题
- UVA - 531 Compromise
- 如何解决加载大图片时内存溢出的问题
- 浅谈协方差矩阵
- PHPExcel使用方法总结
- 如何配置 PLSQL 连接远程 Oracle 服务器
- 最新VMware Workstation 10注册码,绝对可用!
- 关于现在2013.9