JZOJ 1121. Fix

解析

考场时想多了,其实根本不用分阶段
一维状压 (DP) 就行了
可我没想清楚,加了个第几次去稳固一个点的阶段
然后时间就炸了!!!

(Code)

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;

double f[1 << 19] , ans;
int n;
struct points{
	int x , y , z;
}a[20];
struct node{
	double a;
	int b;
}d[20][20];

inline bool cmp(node x , node y){return x.a < y.a;}
inline double calc(points x , points y){ 
	return sqrt(((double)x.x - y.x) * (x.x - y.x) + ((double)x.y - y.y) * (x.y - y.y));
}
inline double min(double x , double y){return x < y ? x : y;}

int main()
{
	while (1)
	{
		scanf("%d" , &n);
		if (n == 0) break;
		for(register int i = 1; i <= n; i++) scanf("%d%d%d" , &a[i].x , &a[i].y , &a[i].z);
		for(register int i = 0; i < (1 << n); i++) f[i] = (double)1e18;
		for(register int i = 1; i < 1 << n; i++) 
		{
			int bz = 1;
			for(register int j = n - 1; j >= 0; j--)
				if (((i >> j) & 1) && (a[j + 1].z != 1)){bz = 0; break;}
			if (bz) f[i] = 0;
		}
		for(register int i = 1; i <= n; i++)
		{
			for(register int j = 1; j <= n; j++)
			{
				d[i][j].a = calc(a[i] , a[j]);
				d[i][j].b = j;
			}
			sort(d[i] + 1 , d[i] + n + 1 , cmp);
		}
		int l = 0;
		for(register int i = 1; i < 1 << n; i++)
		{
			int s = 0;
			for(register int j = n - 1; j >= 0; j--) 
			if ((i >> j) & 1) s++;
			if (s < 2 || f[i] == (double)1e18) continue;
			for(register int j = n - 1; j >= 0; j--)
			if (!((i >> j) & 1))
			{
				int o = 1 , oo = 2;
				while (!(i & (1 << d[j + 1][o].b - 1)) && o <= n) o++;
				oo = o + 1;
				while (!(i & (1 << d[j + 1][oo].b - 1)) && oo <= n) oo++;
				f[i | (1 << j)] = min(f[i | (1 << j)] , f[i] + d[j + 1][o].a + d[j + 1][oo].a);
			}
		}
		ans = min((double)1e18 , f[(1 << n) - 1]);
		if (ans == (double)1e18) printf("No Solution
");
		else printf("%.6lf
" , ans);
	}
}
原文地址:https://www.cnblogs.com/leiyuanze/p/13469526.html