一道树形dp裸体,自惭形秽没有想到
首先由于两两圆不能相交(可以相切)就决定了一个圆和外面一个圆的包含关系
又可以发现这样的树中,奇数深度的圆+S,偶数深度的圆-S
就可以用树形dp

我又写挫了= =

#include<cmath>
#include<map>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<set>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 1e3+5;
const int INF = 0x3f3f3f3f;
const double pi = acos(-1.0);
#define MP(x, y) make_pair(x, y) int X[N], Y[N], R[N]; int ord[N];
double S[N];
struct Node{
int to, nx;
}E[N*2];
int head[N], tot;
int dep[N];
double dp[N][2][2];
int cmp(int a, int b) {
return R[a] < R[b];
}
void gmax(double &a, double b) {
if(a < b) a = b;
} void add(int fr, int to) {
E[tot].to = to; E[tot].nx = head[fr]; head[fr] = tot++;
dep[to] ++;
}
int Incir(int a, int b) {
if(R[a] <= R[b]) return 0;
double dis = sqrt(1ll*(X[a] - X[b])*(X[a] - X[b]) + 1ll*(Y[a] - Y[b])*(Y[a] - Y[b]));
if(dis + 1.0*R[b] <= 1.0*R[a]) return 1;
else return 0;
}
void dfs(int x) {
double tmp[2][2][2];
memset(tmp, 0, sizeof(tmp)); for(int i = head[x]; ~i; i = E[i].nx) {
int to = E[i].to; dfs(to);
} for(int i = head[x]; ~i; i = E[i].nx) {
int to = E[i].to;
tmp[1][0][0] += dp[to][1][0]; tmp[1][0][1] += dp[to][1][1]; tmp[1][1][0] += dp[to][0][0]; tmp[1][1][1] += dp[to][0][1];
tmp[0][0][0] += dp[to][0][1]; tmp[0][0][1] += dp[to][0][0]; tmp[0][1][0] += dp[to][1][1]; tmp[0][1][1] += dp[to][1][0];
}
for(int i = 0; i < 2; ++i) for(int j = 0; j < 2; ++j) dp[x][i][j] = max(tmp[0][i][j] +( (j^1)? S[x]:-S[x]), tmp[1][i][j] +( (i^1)?S[x]:-S[x]));
// printf("%d %.2f %.2f %.2f %.2f %.2f %.2f\n",x, dp[x][0][0], dp[x][0][1], dp[x][1][0], dp[x][1][1], tmp[1][0][0] +( (0^1)?S[x]:-S[x]), S[x]);
} int main() {
int n;
while(~scanf("%d", &n)) {
memset(dep, 0, sizeof(dep));
memset(head, -1, sizeof(head));
tot = 0; for(int i = 0; i < n; ++i) {
scanf("%d %d %d", &X[i], &Y[i], &R[i]);
ord[i] = i;
S[i] = pi*R[i]*R[i];
}
sort(ord, ord+n, cmp); // for(int i = 0; i < n; ++i) printf("%d ", ord[i]); printf("\n");
for(int i = 0; i < n; ++i) {
for(int j = i+1; j < n; ++j) {
if(Incir(ord[j], ord[i])) { add(ord[j], ord[i]); break; }
}
} double ans = 0;
for(int i = 0; i < n; ++i) {
if(!dep[i]) {
dfs(i);
ans += dp[i][0][0];
}
}
printf("%.9f\n", ans);
}
return 0;
}

CF#418 Div2 D. An overnight dance in discotheque的更多相关文章

  1. Codeforces Round #418 (Div. 2) D. An overnight dance in discotheque

    Codeforces Round #418 (Div. 2) D. An overnight dance in discotheque 题意: 给\(n(n <= 1000)\)个圆,圆与圆之间 ...

  2. An overnight dance in discotheque

    An overnight dance in discotheque time limit per test 2 seconds memory limit per test 256 megabytes ...

  3. codeforces 814D An overnight dance in discotheque

    题目链接 正解:贪心. 首先我们可以计算出每个圆被多少个圆覆盖. 很显然,最外面的圆是肯定要加上的. 然后第二层的圆也是要加上的.那么第三层就不可能被加上了.同理,第四层的圆又一定会被加上. 然后我们 ...

  4. An overnight dance in discotheque CodeForces - 814D (几何)

    大意: 给定n个不相交的圆, 求将n个圆划分成两部分, 使得阴影部分面积最大. 贪心, 考虑每个连通块, 最外层大圆分成一部分, 剩余分成一部分一定最优. #include <iostream& ...

  5. CodeForces 814D An overnight dance in discotheque(贪心+dfs)

    The crowdedness of the discotheque would never stop our friends from having fun, but a bit more spac ...

  6. codeforces 814 D. An overnight dance in discotheque (贪心+bfs)

    题目链接:http://codeforces.com/contest/814/problem/D 题意:给出奇数个舞者,每个舞者都有中心坐标和行动半径,而且这些点组成的园要么相互包含要么没有交集求,讲 ...

  7. codeforces round 418 div2 补题 CF 814 A-E

    A An abandoned sentiment from past 水题 #include<bits/stdc++.h> using namespace std; int a[300], ...

  8. cf 442 div2 F. Ann and Books(莫队算法)

    cf 442 div2 F. Ann and Books(莫队算法) 题意: \(给出n和k,和a_i,sum_i表示前i个数的和,有q个查询[l,r]\) 每次查询区间\([l,r]内有多少对(i, ...

  9. CF#603 Div2

    差不多半年没打cf,还是一样的菜:不过也没什么,当时是激情,现在已是兴趣了,开心就好. A Sweet Problem 思维,公式推一下过了 B PIN Codes 队友字符串取余过了,结果今天早上一 ...

随机推荐

  1. java 虚拟机--新生代与老年代GC [转]

    原文链接:http://www.360doc.com/content/12/1023/16/9615799_243296263.shtml 1. Java堆中各代分布: 图1:Java堆中各代分布 Y ...

  2. BZOJ 3209: 花神的数论题 [数位DP]

    3209: 花神的数论题 题意:求\(1到n\le 10^{15}\)二进制1的个数的乘积,取模1e7+7 二进制最多50位,我们统计每种1的个数的数的个数,快速幂再乘起来就行了 裸数位DP..\(f ...

  3. getHibernateTemplate() VS getSession()

    如题所示,对于这个问题,官网文档已给出答案,详见: /** * Obtain a Hibernate Session, either from the current transaction or * ...

  4. C语言之prinf的用法

    1. n换行字符 1).直接输出内容 printf("哈哈\n"); 2).带参数的输出 int i = 10 ; %d:输入控制符 printf ("%d\n" ...

  5. Go语言获取命令行参数

    package main import ( "os" "fmt" ) func main() { args := os.Args //获取用户输入的所有参数 { ...

  6. Go语言极速入门手册

    Github: https://github.com/coderzh/CodeTips /* gotips_test.go: Golang速学速查速用代码手册 Source: github.com/c ...

  7. C控制语句:分支和跳转

    小技巧:程序return前加个getchar();可以让程序停住.%%可以打印使printf()中打印出%号 #include<stdio.h>#define SPACE ''int ma ...

  8. for 循环中的 i 变量问题

    1:如何点击每一个 li 的时候 alert 输出其index? <ul id="test"> <li>111</li> <li>2 ...

  9. appium+Python 启动app(三)登录

    我们根据前面的知识点,用uiautomatorviewer工具来获取我们当前的元素 (注:uiautomatorviewer 是 android sdk 自带的) 知识点:appium的webdriv ...

  10. IE8兼容问题总结---trim()方法

    1.IE8不支持,jquery的trim()去空格的方法 错误表现 : 会报错,对象不支持此属性或方法; 解决办法 : 使用正则匹配空格 例如 : /^\s+|\s+$/greplace(/^\s+| ...