这题当时我直接裸搜了,其实应该想到的 15! 肯定要超时啊。。。
不过这题当时LG也做了,他过了,看他代码,用的状态压缩。。
后来看状态压缩的论文,了解了下,今天再看他的代码就很明白了= =。。基本上照抄了一遍囧,改了点小地方。。
位运算的状态压缩,相当于把所有状态都考虑到了,这个题也就2^15个状态,所以时间复杂度比N!小多了,然后枚举一个状态的情况即可。
也就是枚举两个圆,看是否相交,很神奇捏。。2^N*N的时间复杂度。。
给BUPT发邮件了。。这题没加他们题目列表。。。没验证呢。。
不过我觉得是对的哈~~
P.S. BUPT加上题啦~~~嘿嘿
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define FOR(i,s,t) for(int i=(s); i<(t); i++)
#define BUG puts("here!!!")
#define STOP system("pause")
#define file_r(x) freopen(x, "r", stdin)
#define file_w(x) freopen(x, "w", stdout)
using namespace std;
const int MAX = 20;
struct point {
int x, y, r;
void get()
{
scanf("%d%d%d", &x, &y, &r);
}
};
point p[MAX];
long long disp2p(point a,point b)
{
return (a.x - b.x)*1ll*(a.x - b.x) + (a.y - b.y)*1ll*(a.y - b.y);
}
bool inst(int x, int y)
{
return disp2p(p[y], p[x]) <= (p[y].r + p[x].r)*1ll*(p[y].r + p[x].r);
}
bool BIN(int i, int n)
{
FOR(j, 0, n)
FOR(k, j+1, n)
if( ( (1<<j) & i ) && ((1<<k) & i ) )
if( inst(j, k) ) // 如果相交
return false;
return true;
}
int solve(int n)
{
int ans, mmax = 0;
FOR(i, 0, 1<<n)
{
ans = 0;
bool f = BIN(i, n);
if( f )
FOR(k, 0, n)
if( (1<<k) & i )
ans += p[k].r * p[k].r;
mmax = max(mmax, ans);
}
return mmax;
}
int main()
{
int n, ncases;
scanf("%d", &ncases);
while( ncases-- )
{
scanf("%d", &n);
FOR(i, 0, n)
p[i].get();
int ans = solve(n);
printf("%d\n", ans);
}
return 0;
}