uva 1016 - Silly Sort(置换的灵活应用)
2013-09-13 09:34
288 查看
题意:给你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 比较两者最小值即答案
//保存周期
//直接求答案 快些
解析:通过置换可以发现原序列可以分为多个周期(循环)的变换,如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 10005 int k,n,a ,c ,b ,vis ,minx; long long res; vector<int> w ; 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 - 12103 Leonardo's Notebook (置换乘法的应用)
- Linux 文件排序sort 应用
- 灵活应用js调试技巧解决样式问题的步骤分享
- 《数据结构》实验一:VC编程环境灵活应用
- 灵活地应用抽象工厂方法模式
- uva 10791 Minimun Sum Lcm(算术基本定理应用,推荐)
- uva11396 dfs应用
- 数据结构 实验一:VC编程环境灵活应用
- UVA.12096 The SetStack Computer ( 好题 栈 STL混合应用)
- DataSet与控件的灵活应用
- uva 11368 - Nested Dolls(sort+greedy+binary_search)
- 气泡 弹出 bootstrap-popover的配置与灵活应用
- Uva10294 Arif in Dhaka (置换问题)
- Hadoop应用——sort
- uva_10881_Piotr's Ants (模拟,Sort)
- UVA 11995 I Can Guess the Data Structure! (STL的应用)
- 【uva 10294】 Arif in Dhaka (First Love Part 2) (置换,burnside引理|polya定理)
- Uva 10815 安迪的第一个字典 set数组应用实例