题目链接

题解:这道题,首先可以发现,圆与圆关系只有内含与外离,

所以可以建立出一个树形结构,

每个圆的父亲是与这个圆半径相差最小且包含这个圆的圆,

这样,整个一张图形成了一个森林,可以将圆按半径排序后O(n^2)建立出来。

Solution 1 :  可以对这个森林进行树形dp,

因为需要将森林分成两个部分,

而且容易发现,对于新形成的森林,深度为奇数的圆贡献为S,偶数为-S,

于是对于每棵树分别dp,

f[i][0/1][0/1]表示以i为根,2个01变量分别表示到达i时两棵树的深度的奇偶性,

显然,因为是树上深度相关,这两个01变量应该从根到儿子进行转移,

通过枚举在i位置的选择,dp数组的求解由儿子到根进行转移。

(这么设状态可以保证儿子对父亲的贡献总是为正,如果儿子对父亲贡献出现负值,就不符合dp的最优子结构性质了)

(菜鸡博主开始设置的状态会使儿子对父亲的贡献可能为负,所以导致比赛时GG   我好菜啊高清重置版)

Code:

#include <bits/stdc++.h>
#define eps 1e-12
double pi=acos(-1.0);
using namespace std;
struct node
{double x,y,r;
}t[1005];
int n;
int fa[1005];
double f[1005][2][2];
vector <int> vec[1005];
inline bool cmp(node a,node b)
{return a.r>b.r;}
void dfs(int pos)
{if (vec[pos].size()==0)
{f[pos][0][0]=-t[pos].r*t[pos].r*pi;
f[pos][1][1]=t[pos].r*t[pos].r*pi;
f[pos][0][1]=t[pos].r*t[pos].r*pi;
f[pos][1][0]=t[pos].r*t[pos].r*pi;
return;
}
/*
f[pos][0][0]=-t[pos].r*t[pos].r*pi;
f[pos][0][1]=-t[pos].r*t[pos].r*pi;
f[pos][1][0]=t[pos].r*t[pos].r*pi;
f[pos][1][1]=t[pos].r*t[pos].r*pi;
f[pos][0][0]=-t[pos].r*t[pos].r*pi;
f[pos][0][1]=t[pos].r*t[pos].r*pi;
f[pos][1][0]=-t[pos].r*t[pos].r*pi;
f[pos][1][1]=t[pos].r*t[pos].r*pi;
*/
double s[2][2];
memset (s,0,sizeof(s));
for (int i=0;i<vec[pos].size();i++)
{dfs(vec[pos][i]);
int son=vec[pos][i];
s[0][0]+=f[son][0][0];
s[0][1]+=f[son][0][1];
s[1][0]+=f[son][1][0];
s[1][1]+=f[son][1][1];
}
double siz=t[pos].r*t[pos].r*pi;
f[pos][0][0]=max(s[0][1]-siz,s[1][0]-siz);
f[pos][1][0]=max(s[0][0]+siz,s[1][1]-siz);
f[pos][1][1]=max(s[0][1]+siz,s[1][0]+siz);
f[pos][0][1]=max(s[0][0]+siz,s[1][1]-siz);
}
int main (){int i,j;scanf ("%d",&n);for (i=1;i<=n;i++){scanf ("%lf%lf%lf",&t[i].x,&t[i].y,&t[i].r);}sort(t+1,t+n+1,cmp);for (i=1;i<=n;i++){for (j=i-1;j>=1;j--){if (((t[i].x-t[i].r)+eps>t[j].x-t[j].r)&&((t[i].x+t[i].r)-eps<t[j].x+t[j].r)&&((t[i].y-t[i].r)+eps>t[j].y-t[j].r)&&((t[i].y+t[i].r)-eps<t[j].y+t[j].r)){vec[j].push_back(i);fa[i]=j;break;}}}double ans=0;for (i=1;i<=n;i++){if (!fa[i]){dfs(i);double maxn=-1e18;ans+=f[i][1][1];}}printf ("%.12lf\n",ans);return 0;
}



Solution 2:  非常妙的贪心,建出树之后,
对于树上某个位置i,只要能够使它的贡献为正,就让它贡献为正数。
正确性:对于每个圆,若使它贡献为正,与让它贡献为负时相比,答案相差了2*Si.
而对于这个圆所对应的子树的选择,整个子树对于答案的贡献不会小于-Si,也不会大于Si,
所以显然这种情况下让这个圆贡献为正所取得的收益更大,所以贪心是正确的。
Code:
#include <bits/stdc++.h>
#define eps 1e-12
double pi=acos(-1.0);
using namespace std;
struct node
{double x,y,r;
}t[1005];
inline bool cmp(node a,node b)
{return a.r>b.r;}
int n;
int fa[1005],dep[1005];
int main (){int i,j;scanf ("%d",&n);for (i=1;i<=n;i++){scanf ("%lf%lf%lf",&t[i].x,&t[i].y,&t[i].r);}sort(t+1,t+n+1,cmp);for (i=1;i<=n;i++){for (j=i-1;j>=1;j--){if (((t[i].x-t[i].r)+eps>t[j].x-t[j].r)&&((t[i].x+t[i].r)-eps<t[j].x+t[j].r)&&((t[i].y-t[i].r)+eps>t[j].y-t[j].r)&&((t[i].y+t[i].r)-eps<t[j].y+t[j].r)){fa[i]=j;break;}}}double ans=0;dep[0]=0;for (i=1;i<=n;i++){dep[i]=dep[fa[i]]+1;}for (i=1;i<=n;i++){if (dep[i]<=2||dep[i]%2==0) {ans+=pi*t[i].r*t[i].r;}else {ans-=pi*t[i].r*t[i].r;}}printf ("%.12lf\n",ans);return 0;
}
												

[Codeforces 814D] An overnight dance in discotheque 树形dp,贪心相关推荐

  1. Codeforces 814D An overnight dance in discotheque 贪心

    题意 题解 Codeforces 814D An overnight dance in discotheque 物语场!!!!之后的可怜和命运石之门--哈哈哈哈哈哈哈-- 题意 平面直角坐标系中有n个 ...

  2. codeforces 816 E. Karen and Supermarket(树形dp)

    题目链接:http://codeforces.com/contest/816/problem/E 题意:有n件商品,每件有价格ci,优惠券di,对于i>=2,使用di的条件为:xi的优惠券需要被 ...

  3. CodeForces - 1453E Dog Snacks(树形dp+贪心)

    题目链接:点击查看 题目大意:给出一棵有根树,现在需要选择一个最小的 k 值,可以满足下列的 n 次操作: 起始时位于点 1(根节点) 每一步选择一个未被遍历的节点中,距离最近的,且必须满足此距离小于 ...

  4. Codeforces 835 F Roads in the Kingdom(树形dp)

    F. Roads in the Kingdom(树形dp) 题意: 给一张n个点n条边的无向带权图 定义不便利度为所有点对最短距离中的最大值 求出删一条边之后,保证图还连通时不便利度的最小值 $n & ...

  5. A. Parsa‘s Humongous Tree(树形DP + 贪心)

    Problem - 1528A - Codeforces 两个玩家正在玩一个游戏.他们有一个整数1,2,...,n的排列组合(排列组合是一个数组,其中从1到n的每个元素正好出现一次).这个排列组合没有 ...

  6. 2020CCPC(秦皇岛) - Kingdom‘s Power(树形dp+贪心)

    题目大意:给出一棵 n 个节点的有根树,点 1 为根节点,现在在根节点有无穷多个士兵,每一秒可以控制任意一个士兵向任意一个单位移动一步,士兵移动到的点会被永久占领,现在问最少需要经过多少秒,才能将所有 ...

  7. The Lost House POJ - 2057(树形dp+贪心 (双线最优子结构问题))

    思路 题意:有一只蜗牛爬上树睡着之后从树上掉下来,发现后面的"房子"却丢在了树上面, 现在这 只蜗牛要求寻找它的房子,它又得从树根开始爬起,现在要求一条路径使得其找到房子 所要爬行 ...

  8. CodeForces - 1220E Tourism(边双缩点+树形dp)

    题目链接:点击查看 题目大意:给出一个由n个点和m条边构成的无向图,每个点都有一个权值,现在给出起点st,问从起点出发,如何规划路线可以使得途径的权值最大,唯一的约束是一条边不能连续经过,比如当前从u ...

  9. [POI2014]FAR-FarmCraft 树形DP + 贪心思想

    (感觉洛谷上题面那一小段中文根本看不懂啊,好多条件都没讲,直接就是安装也要一个时间啊,,,明明不止啊!还好有百度翻译......) 题意:一棵树,一开始在1号节点(root),边权都为1,每个点有点权 ...

最新文章

  1. 机器学习和洗衣机的关系?
  2. 纯 CSS 实现三角形尖角箭头的实例
  3. github加速-解决GitHub访问速度很慢的问题
  4. C语言程序练习-L1-018 大笨钟 (10分)
  5. MVC常见的控制器,接口,数据层之间的操作
  6. 靓仔落泪,性能问题定位难倒我了
  7. 面试官:int和Integer有什么区别?为什么要有包装类?
  8. 服务器安全之iptables iptables
  9. 如何高效率学Web前端 怎么规划前端学习路线
  10. MyBatis模糊查询like的三种方式
  11. 【图像分割】基于matlab改进的细菌觅食算法双阈值图像分割【含Matlab源码 069期】
  12. 温度监视器的设计与制作
  13. hbase 基本命令
  14. java启动tomcat9闪退
  15. 细则从哈利·波特与来自您好麻雀船长
  16. leetcode 198打家劫舍
  17. #93 高精度除低精度
  18. 为什么MacBook连接不上阿里云服务器
  19. 科大讯飞SDK的使用
  20. oracle 度分秒转小数点,角度的度分秒与小数点格式互相转换

热门文章

  1. C Programming学习笔记【谭浩强老师编】(第三章顺序程序设计)04 C语句
  2. AutoCAD 二次开发语言的选择
  3. java多线程读取文件_java多线程读写同一个文件
  4. 行云管家荣膺《中国网络安全行业全景图(第九版)》收录
  5. 《朗读者》:在历史的重负里前行
  6. 飞秋2010 开发团队建设与管理的一些心得
  7. Adobe Photoshop CS6 Extended试用版已经到期了
  8. 根据手机号码查询手机归属地和手机运营商等信息
  9. Linux系统运行时参数命令--Linux基础命令和工具
  10. 最新kali之pixiewps