设为首页 加入收藏

TOP

uva 1016 - Silly Sort(置换+贪心)
2015-07-20 17:55:22 】 浏览:5850
Tags:uva 1016 Silly Sort 置换 贪心

题目链接:uva 1016 - Silly Sort

题目大意:给定一个长度为n的序列,每次操作可以交换任意两个数的位置,代价为两个数的和,求最小代价,将序列排成有序的。

解题思路:给定序列根据数的大小映射成一个置换,分解置换的循环,对于每个循环中,肯定是用值最小的逐个去交换的代价最小,但是要考虑,可以将最小的值与序列中最小值交换,用它代替去交换,最后再换回来。取两种情况中最优的。

#include 
   
     #include 
    
      #include 
     
       using namespace std; const int maxn = 1005; int n, arr[maxn], rec[maxn], pos[maxn]; int rep, v[maxn]; void init () { memset(v, 0, sizeof(v)); memset(rec, -1, sizeof(rec)); rep = maxn; for (int i = 0; i < n; i++) { scanf("%d", &arr[i]); pos[i] = arr[i]; rep = min(arr[i], rep); } sort(pos, pos + n); for (int i = 0; i < n; i++) rec[pos[i]] = i; for (int i = 0; i < n; i++) pos[i] = rec[arr[i]]; /* for (int i = 0; i < n; i++) printf("%d ", pos[i]); printf("\n"); */ } int solve () { int ret = 0; for (int i = 0; i < n; i++) { if (v[i]) continue; int j = i, c= 0; int ans = 0, tmp = maxn; while (v[j] == 0) { tmp = min(tmp, arr[j]); ans += arr[j]; v[j] = 1; c++; j = pos[j]; } ans -= tmp; ret += ans + min(tmp * (c-1), tmp * 2 + rep * (c+1)); } return ret; } int main () { int cas = 1; while (scanf("%d", &n) == 1 && n) { init(); printf("Case %d: %d\n\n", cas++, solve()); } return 0; }
     
    
   
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇uva 10601 - Cubes(置换) 下一篇ZOJ 1074 To the Max (DP)

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目