zoukankan      html  css  js  c++  java
  • codevs 2845 排序的代价

    /*
    比较简单的置换群题
    首先排成升序 每个元素都有想去的位置
    先找轮换 比如1->2 2->3 3->1 那么(1.2.3)就是一个轮换
    可以看出他们之间互不影响 然后开始处理每个轮换
    可以用数学归纳法证明处理每个小的需要最少换n-1次
    为了让代价最小我们那c最小的元素当做中间值
    这里有反例 就是如果有一个c很小的数
    我们先把这个轮换里的min和这个交换 然后拿这个完成n-1次
    最后再换回来 这样可能更优 所以min一下就好了 
    (讲的太不详细了 具体的可以仔细的上网学习一下) 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 1010
    #define inf 0x3f3f3f3f
    using namespace std;
    int n,f[maxn],ans,cas,sum,mii,Mii,cnt;
    struct node{
        int c,to;
        bool operator < ( const node & x ) const {
            return c<x.c;
        }
    }p[maxn];
    void Clear(){
        memset(f,0,sizeof(f));
        Mii=inf;ans=0;
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF){
            Clear();
            for(int i=1;i<=n;i++){
                scanf("%d",&p[i].c);
                Mii=min(Mii,p[i].c);
                p[i].to=i;
            }
            sort(p+1,p+1+n);
            for(int i=1;i<=n;i++)
                if(!f[i]){
                    sum=0;mii=inf;cnt=0;
                    int r=i;
                    while(!f[r]){
                        mii=min(mii,p[r].c);
                        sum+=p[r].c;cnt++;
                        f[r]=1;r=p[r].to;
                    }
                    ans+=sum+min((cnt-2)*mii,(cnt+1)*Mii+mii);
                }
            if(ans==0)break;
            printf("Case %d: %d
    ",++cas,ans);
        }
        return 0;
    }
  • 相关阅读:
    常用查找算法总结
    cout<<endl 本质探索
    C语言字符串操作函数实现
    Shell编程实例
    Linux搭建SVN服务器
    Linux下搭建gtk+2.0开发环境
    Cairo编程
    DirectFB编程
    Ubuntu安装与配置
    Android学习之仿QQ側滑功能的实现
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/5864782.html
Copyright © 2011-2022 走看看