poj3270

这题考察的是契科夫格里斯特环。。。。。。。

。。。。。好吧我承认我在吹牛逼。。。

利用置换环的思想,我们可以找出一些置换环,对每个置换环我们可以轻易的知道这样几个规律。

令置换环长度为n,首先置换次数至少是n-1,并且每个元素至少被置换一次。如果本环内置换的话,置换的代价至少是这样的sum-mina+(n-1)*mina。我们发现这种代价是可以实现的只要每次都用最小的元素去归位另一些元素,但是这是本环内部的置换,而当本环内部的最小元素去置换整个数组中的最小元素时,可能会有更小的情况,以下是证明,如果与其他置换环中的元素交换的话与且只与其他环中的最小元素交换能是最优的

从sum-mina+(n-1)*mina角度来讲只有mina变得更小才能抵消掉交换所带来的增加值,交换后形成一个更大的环如果用本环被换的代价是等于刚刚的交换后再换回来的代价的。

#include<iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
using namespace std;
const int maxa = 100005;
int a[maxa], b[maxa], c[maxa];
int judge[maxa];
int main(){
    int n;
    while(scanf("%d", &n)!=EOF){
        for(int i = 0;i  < n; i++){
            scanf("%d", &a[i]);
            b[i] = a[i];
        }
        sort(b, b+n);
        for(int i = 0;i  < n; i++){
            c[b[i]] = i;
        }
        memset(judge, 0, sizeof(judge));
        int ans = 0;
        for(int i = 0; i < n; i++){
            int j = i;
            int sum = 0;
            int k = 0;
            if(judge[i])continue;//printf("*");
            int mina = a[j];
            while(judge[j] != 1){k ++;
                judge[j] = 1;
                sum += a[j];
                j = c[a[j]];
                mina = min(mina, a[j]);
            }sum -= mina;
            //cout<<mina<<"<<"<<sum<<endl;
            ans += min((k-1)*mina+sum, (k-1)*b[0]+sum+2*(b[0]+mina));
        }
        printf("%d\n", ans);
    }
}

时间: 2024-11-07 04:13:57

poj3270的相关文章

POJ3270 cow sorting 【polya】

题目描述: 给你一个数字序列(每个数字唯一),每次你可以交换任意两个数字,代价为这两个数字的和,问最少用多少代价能把这个序列按升序排列好. 题目的具体做法是参考刘汝佳的<算法艺术与信息学奥赛>大概思路是:以后再用别种方法解, 1.找出初始状态和目标状态.明显,目标状态就是排序后的状态. 2.画出置换群,在里面找循环.例如,数字是8 4 5 3 2 7 明显,                                   目标状态是2 3 4 5 7 8,能写为两个循环:(8 2 7)(4

poj3270 Cow Sorting

置换群的第二题,一开始总是tle,后来一思考,置换根本不是这个情况,置换是一种排列,就用了几个数组将输入的数进行操作,最后A了,对置换有一些了解了. #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 10000+10; int n,least; int a[maxn],b[1000010],s[maxn],tmp[1000010]; v

acm常见算法及例题

转自:http://blog.csdn.net/hengjie2009/article/details/7540135 acm常见算法及例题 初期:一.基本算法:     (1)枚举. (poj1753,poj2965)     (2)贪心(poj1328,poj2109,poj2586)     (3)递归和分治法.     (4)递推.     (5)构造法.(poj3295)     (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)二.图算法

ACM算法总结及刷题参考

参考:http://bbs.byr.cn/#!article/ACM_ICPC/11777 OJ上的一些水题(可用来练手和增加自信)(poj3299,poj2159,poj2739,poj1083,poj2262,poj1503,poj3006,poj2255,poj3094) 初期: 一.基本算法: (1)枚举. (poj1753,poj2965)    (2)贪心(poj1328,poj2109,poj2586)    (3)递归和分治法.     (4)递推.     (5)构造法.(po

POJ题目推荐(转载)

POJ推荐50题1.标记“难”和“稍难”的题目可以看看,思考一下,不做要求,当然有能力的同学可以直接切掉.2.标记为A and B的题目是比较相似的题目,建议大家两个一起做,可以对比总结,且二者算作一个题目.3.列表中大约有70个题目.大家选做其中的50道,且每类题目有最低数量限制.4.这里不少题目在BUPT ACM FTP上面都有代码,请大家合理利用资源.5.50个题目要求每个题目都要写总结,养成良好的习惯.6.这个列表的目的在于让大家对各个方面的算法有个了解,也许要求有些苛刻,教条,请大家谅

POJ题目分类

初期: 一.基本算法:     (1)枚举. (poj1753,poj2965)     (2)贪心(poj1328,poj2109,poj2586)     (3)递归和分治法.     (4)递推.     (5)构造法.(poj3295)     (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)二.图算法:     (1)图的深度优先遍历和广度优先遍历.     (2)最短路径算法(dijkstra,bellman-ford,floyd,he

嗷嗷嗷,kuangbin大大博客上拉的题

正在学(learning),未学(waiting),已学(cut  vovering) 初期:一.基本算法:     (1)枚举. (poj1753,poj2965)     (2)贪心(poj1328,poj2109,poj2586)     (3)递归和分治法.     (4)递推.     (5)构造法.(poj3295)     (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)二.图算法:     (1)图的深度优先遍历和广度优先遍历.  

转:转一个搞ACM需要的掌握的算法. .

要注意,ACM的竞赛性强,因此自己应该和自己的实际应用联系起来.  适合自己的才是好的,有的人不适合搞算法,喜欢系统架构,因此不要看到别人什么就眼红,  发挥自己的长处,这才是重要的. 第一阶段:练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码,  因为太常用,所以要练到写时不用想,10-15分钟内打完,甚至关掉显示器都可以把程序打  出来.  1.最短路(Floyd.Dijstra,BellmanFord)  2.最小生成树(先写个prim,kruscal要用并查集,不好写)

算法初学者指南

摘自网络,对于这个训练计划,我只能膜拜,~ 第一阶段:练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码, 因为太常用,所以要练到写时不用想,10-15 分钟内打完,甚至关掉显示器都可以把程序打 出来. 1.最短路(Floyd.Dijstra,BellmanFord) 2. 最小生成树(先写个prim,kruscal要用并查集,不好写) 3.大数(高精度)加减乘除 4.二分查找. (代码可在五行以内) 5.叉乘.判线段相交.然后写个凸包. 6.BFS.DFS,同时熟练hash表(