这题当时我直接裸搜了,其实应该想到的 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; }