您的位置:首页 > 产品设计 > UI/UE

uva_10911 - Forming Quiz Teams ( 状态压缩DP )

2012-12-04 19:13 369 查看
这里的状态使用二进制表示,例如有4个数,1,2,3,4,分别表示坐标的代号,那么可以用一个正整数表示这个状态, 例如组合1,4这个,则表示为十进制的9(二进制:1001)
枚举所有组合就ok了,其他的都是位运算,如有不通,看code.

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

#define MAXN    100
#define MAXCHAR 100
#define MAXV    (1<<16)
#define INF     0x7fffffff

char str[MAXCHAR];
double x[MAXN], y[MAXN], dp[MAXV];

int valid(const int &x, const int &max_bit)
{
int cnt(0);
for(int i = 0; i < max_bit; i ++) {
if( (1<<i)&x ) {
cnt ++;
}
}
return !(cnt&1);
}

double cost(const int &dp_idx, const int &x_idx, const int &y_idx)
{
double tmpx(x[x_idx]-x[y_idx]), tmpy(y[x_idx]-y[y_idx]);
return ((INF == dp[dp_idx])? 0.0 : dp[dp_idx])+sqrt(tmpx*tmpx+tmpy*tmpy);
}

double dynamic_pro(const int &max_bit)
{
int tar( (1<<max_bit)-1 ), tmp_idx;
for(int i = 0; i <= tar; i ++) {
dp[i] = INF;
}
for(int n = 0; n <= tar; n ++) {
if( !valid(n, max_bit) ) {
continue;
}
for(int i = 0; i < max_bit; i ++) {
if( n&(1<<i) ) {
continue;
}
for(int j = i+1; j < max_bit; j ++) {
if( n&(1<<j) ) {
continue;
}
tmp_idx = n|(1<<i)|(1<<j);
dp[tmp_idx] = min(dp[tmp_idx], cost(n, i, j));
}
}
}
return dp[tar];
}

int main(int argc, char const *argv[])
{
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
#endif
int n, cas(1);
while( scanf("%d", &n) && n ) {
for(int i = 0; i < (n<<1); i ++) {
scanf("%s %lf %lf",str, &x[i], &y[i]);
}
printf("Case %d: %.2lf\n", cas ++, dynamic_pro(n<<1));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: