UVA 10911 - Forming Quiz Teams

来源:互联网 发布:明朝三百年 知乎 编辑:程序博客网 时间:2024/05/23 13:09
import java.io.*;import java.math.BigInteger;import java.util.*;public class Main {    static int N = 1<<21;    static boolean marked[] = new boolean[N];    static double dp[] = new double[N];    static double x[] = new double[30];    static double y[] = new double[30];    static double dis[][] = new double[30][30];    public static double dfs(int start,int n){        if(marked[start]) return dp[start];        marked[start] = true;        if(start==0) return dp[start]=0;        dp[start] = Integer.MAX_VALUE;        for(int i=0;i<n;i++){        if((start&(1<<i))==1<<i){        for(int j=i+1;j<n;j++){        if((start&(1<<j))==1<<j){        int next = start;        next&=~(1<<i);        next&=~(1<<j);        dp[start] = Math.min(dp[start],dfs(next,n)+dis[i][j]);        }        }        }        }        return dp[start];    }    public static void main (String [] args) throws Exception {        Scanner scan = new Scanner(System.in);        int cases = 1;        while(true){            int n = Integer.parseInt(scan.nextLine());            if(n==0) return;            n*=2;            Arrays.fill(dp, 0);            Arrays.fill(x, 0);            Arrays.fill(y, 0);            Arrays.fill(marked, false);            for(int i=0;i<n;i++){                String s[] = scan.nextLine().split(" ");                x[i] = Double.parseDouble(s[1]);                y[i] = Double.parseDouble(s[2]);            }            for(int i=0;i<n;i++){                for(int j=0;j<n;j++){                    dis[i][j] = Math.sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));                }            }            double ans = dfs((1<<n)-1,n);            System.out.print("Case "+(cases++)+": ");            System.out.printf("%.2f\n",ans);        }    }}


其实是没什么好方法的,其实就是dfs爆搜,由于情况太多必须做标记,类似于那种走迷宫之类的搜索

这个转化不是太明显,是用bit位处理数字。这个转化就是每次取出两个学生来,这两个分别是i和j

然后把dis存起来,并且bit位归0以保证下次不重复取学生

复杂度应该是N阶乘吧,但是N的范围仅仅是8,这个就没啥好说的了。

这题我是没想出来了,还是要多学习

原创粉丝点击