zoukankan      html  css  js  c++  java
  • uva 10911

    题目链接:10911 - Forming Quiz Teams


    题目大意:给出2 * n个选手的坐标, 要求将所有的选手分成n组, 每组两个人, 所有组的两个人之间的距离之和要最小, 输出最小值。


    解题思路:网络赛的时候写过类似的题目, 只不过是选4个点做正方形,所以思路很明确,每次选取任意两个点配对,递归搜索,并记录下来。然后我不是用未运算来记录点的状态,而开了个数组,因为位运算用不熟。


    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    const int N = 20;
    const int MAX = 1 << 20;
    
    struct state {
    	int x;
    	int y;
    }tmp[N];
    int n, vis[N];
    double dis[MAX];
    
    void read() {
    	char name[N];
    	memset(dis, 0, sizeof(dis));
    	memset(tmp, 0, sizeof(tmp));
    	n = n * 2;
    	for (int i = 0; i < n; i++) {
    		scanf("%s%d%d", name, &tmp[i].x, &tmp[i].y);
    		vis[i] = 1;
    	}
    }
    
    int change() {
    	int sum = 0;
    	for (int i = 0; i < n; i++)
    		sum = sum * 2 + vis[i];
    	return sum;
    }
    
    double dist(int a, int b) {
    	return sqrt( pow(tmp[a].x - tmp[b].x, 2) + pow(tmp[a].y - tmp[b].y, 2));
    }
    
    double solve() {
    	int num = change();
    	if (num == 0) return 0;
    	if (dis[num] > 1e-9) return dis[num];
    
    	double& sum = dis[num];
    	sum = MAX;
    	for (int i = 0; i < n; i++) {
    		if (!vis[i]) continue;
    		for (int j = i + 1; j < n; j++) {
    			if (!vis[j]) continue;
    			vis[i] = vis[j] = 0;
    			double p = dist(i, j) + solve();
    			if (p - sum < 1e-9) sum = p;
    			vis[i] = vis[j] = 1;
    		}
    	}
    	return sum;
    }
    
    int main() {
    	int cas = 1;
    	while (scanf("%d", &n), n) {
    		read();
    		printf("Case %d: %.2lf
    ", cas++, solve());
    	}
    	return 0;
    }
    


  • 相关阅读:
    【转】算法的时间复杂度
    FFT 物理意义(转)
    【转】FIR学习1
    【转】DFT DTFT DFS FFT的关系
    【转】TCL中的数组
    【转】setup time和hold time的周期问题(slack)
    【转】TCL语法简介
    【转】亚稳态分析
    ubuntu下Samba服务器搭建
    第一次生成uImage出现的问题解决
  • 原文地址:https://www.cnblogs.com/pangblog/p/3331303.html
Copyright © 2011-2022 走看看