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

      

  • 相关阅读:
    StarUML中时序图
    HTML5/jQuery雷达动画图表 图表配置十分简单
    AspNetPager样式以及属性帮助文档
    IE浏览器img不显示解决
    php表单提交--文件
    javascript继承---组合式继承
    javascript继承--原型链的 继承
    【转】JavaScript 之arguments、caller 和 callee 介绍
    Array对象
    android 系统提示对话框(AlertDialog)的使用
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4028915.html
Copyright © 2011-2022 走看看