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;
    }
    

      

  • 相关阅读:
    调用Config.ini类
    winform用AForge拍照功能
    winform导出csv
    winform导出excel
    net里面using的使用
    DBNULL与null的区别
    mui app在线更新
    redux-thunk初步使用
    初步使用Web Notification 实现浏览器消息通知
    ios唤起键盘后,页面不收回导致元素错位的问题.(譬如固定在底部的自定义键盘等)
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4028915.html
Copyright © 2011-2022 走看看