zoukankan      html  css  js  c++  java
  • POJ 3270

    黑书上的经典题了。我说说解这个题的巧妙的地方吧。

    首先,竟然和置换联系起来了。因为其实一个交换即至少可以使其中一个元素到达指定位置了。和循环置换联合起来,使得一个循环内的数可以一步到达指定位置,很巧妙啊。这样,用循环内的最小的数和其它数交换,需要K-1次的交换即可。另外,也可以把整个数列的最小数 i 和循环内的最小数交换,用 i 来和循环内的其他数交换的权值。 两者权值取最小的即可。

    实在巧妙。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define LL __int64
    #define N 10000
    #define inf (1<<30)
    using namespace std;
    
    int num[N+1];
    bool vis[N+1];
    struct Value{
    	int val,pos;
    }cow[N+1];
    
    bool cmp(Value a,Value b){
    	if(a.val<b.val) return true;
    	return false;
    }
    
    LL minL(LL a,LL b){
    	if(a<b) return a;
    	return b;
    }
    
    
    int main(){
    	int n,res_min,cnt,mi; LL ans,res;
    	while(scanf("%d",&n)!=EOF){
    		res_min=inf;
    		for(int i=1;i<=n;i++){
    			scanf("%d",&cow[i].val);
    			cow[i].pos=i;
    			res_min=min(res_min,cow[i].val);
    		}
    		sort(cow+1,cow+n+1,cmp);
    		for(int i=1;i<=n;i++){
    			num[cow[i].pos]=i;
    		}
    		memset(vis,false,sizeof(vis));
    		ans=0;
    		for(int i=1;i<=n;i++){
    			if(!vis[i]){
    				int k=i; cnt=0; mi=inf; res=0;
    				while(!vis[k]){
    					cnt++;
    					mi=min(mi,cow[k].val);
    					res=res+(LL)cow[k].val;
    					vis[k]=true;
    					k=num[k];
    				}
    				ans=ans+res+minL((LL)(cnt-2)*(LL)mi,(LL)mi+(LL)(cnt+1)*(LL)res_min);
    			}
    		}
    		printf("%I64d
    ",ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    选择筛选
    添加标签2 jquery 和JS
    最全的常用正则表达式大全
    Javascript和ECMAScript二三事
    display:none和visibility: hidden二三事
    说人话
    渐进增强和优雅降级
    css的优先级以及!important的使用
    解决VS如何同时打开两个工程(xp和win7)
    jQuery验证控件jquery.validate.js使用说明+中文API
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4028915.html
Copyright © 2011-2022 走看看