题链:

http://poj.org/problem?id=1873

题解:

计算几何,凸包

枚举被砍的树的集合。求出剩下点的凸包。然后判断即可。

代码:

  1. #include<cmath>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. using namespace std;
  7. const int MAXN=16,INF=0x3f3f3f3f;
  8. const double eps=1e-8;
  9. int sign(double x){
  10. if(fabs(x)<=eps) return 0;
  11. return x<0?-1:1;
  12. }
  13. struct Point{
  14. double x,y;
  15. Point(double _x=0,double _y=0):x(_x),y(_y){}
  16. void Read(){scanf("%lf%lf",&x,&y);}
  17. }D[MAXN],H[MAXN];
  18. typedef Point Vector;
  19. bool operator < (Point A,Point B){return sign(A.x-B.x)<0||(sign(A.x-B.x)==0&&sign(A.y-B.y)<0);}
  20. bool operator == (Point A,Point B){return sign(A.x-B.x)==0&&sign(A.y-B.y)==0;}
  21. Vector operator - (Point A,Point B){return Vector(A.x-B.x,A.y-B.y);}
  22. double operator ^ (Vector A,Vector B){return A.x*B.y-A.y*B.x;}
  23. double operator * (Vector A,Vector B){return A.x*B.x+A.y*B.y;}
  24. int V[MAXN],N,ansS,ansV,ansN;
  25. double L[MAXN],resL;
  26. double GL(Vector A){//Get_Length
  27. return sqrt(A*A);
  28. }
  29. int Andrew(int S){
  30. int hnt=0,k=0,tnt=0;
  31. static Point tmp[MAXN];
  32. for(int i=1;i<=N;i++) if(!(S&(1<<(i-1)))) tmp[++tnt]=D[i];
  33. sort(tmp+1,tmp+tnt+1);
  34. tnt=unique(tmp+1,tmp+tnt+1)-tmp-1;
  35. for(int i=1;i<=tnt;i++){
  36. while(hnt>1&&sign((H[hnt]-H[hnt-1])^(tmp[i]-H[hnt-1]))<=0) hnt--;
  37. H[++hnt]=tmp[i];
  38. } k=hnt;
  39. for(int i=tnt-1;i>=1;i--){
  40. while(hnt>k&&sign((H[hnt]-H[hnt-1])^(tmp[i]-H[hnt-1]))<=0) hnt--;
  41. H[++hnt]=tmp[i];
  42. }
  43. return hnt;
  44. }
  45. double GCPC(int hnt){//Get_Convex_Polygon_Circumference
  46. double C=0;
  47. for(int i=1;i<hnt;i++) C+=GL(H[i+1]-H[i]);
  48. return C;
  49. }
  50. int main(){
  51. double C,nowL;
  52. int nowS,nowV,nowN,Case=0;
  53. while(scanf("%d",&N)&&N){
  54. if(N==0) break;
  55. ansS=(1<<N)-1; ansV=INF; ansN=N; resL=0;
  56. for(int i=1;i<=N;i++)
  57. D[i].Read(),scanf("%d%lf",&V[i],&L[i]);
  58. for(int S=1;S<=(1<<N)-1;S++){
  59. nowS=S; nowN=0; nowL=0; nowV=0;
  60. for(int i=1;i<=N;i++) if(S&(1<<(i-1)))
  61. nowN++,nowV+=V[i],nowL+=L[i];
  62. C=GCPC(Andrew(S));
  63. if(sign(nowL-C)<0) continue;
  64. if(nowV<ansV||(nowV==ansV&&nowN<ansN))
  65. ansS=nowS,ansV=nowV,ansN=nowN,resL=nowL-C;
  66. }
  67. if (Case) puts("");
  68. printf("Forest %d\n",++Case);
  69. printf("Cut these trees:");
  70. for(int i=1;i<=N;i++) if(ansS&(1<<(i-1))) printf(" %d",i);
  71. printf("\nExtra wood: %.2lf\n",resL);
  72. }
  73. return 0;
  74. }

  

●POJ 1873 The Fortified Forest的更多相关文章

  1. POJ 1873 The Fortified Forest [凸包 枚举]

    The Fortified Forest Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 6400   Accepted: 1 ...

  2. POJ 1873 The Fortified Forest(凸包)题解

    题意:二维平面有一堆点,每个点有价值v和删掉这个点能得到的长度l,问你删掉最少的价值能把剩余点围起来,价值一样求删掉的点最少 思路:n<=15,那么直接遍历2^15,判断每种情况.这里要优化一下 ...

  3. POJ 1873 - The Fortified Forest 凸包 + 搜索 模板

    通过这道题发现了原来写凸包的一些不注意之处和一些错误..有些错误很要命.. 这题 N = 15 1 << 15 = 32768 直接枚举完全可行 卡在异常情况判断上很久,只有 顶点数 &g ...

  4. 简单几何(凸包+枚举) POJ 1873 The Fortified Forest

    题目传送门 题意:砍掉一些树,用它们做成篱笆把剩余的树围起来,问最小价值 分析:数据量不大,考虑状态压缩暴力枚举,求凸包以及计算凸包长度.虽说是水题,毕竟是final,自己状压的最大情况写错了,而且忘 ...

  5. POJ 1873 The Fortified Forest

    题意:是有n棵树,每棵的坐标,价值和长度已知,要砍掉若干根,用他们围住其他树,问损失价值最小的情况下又要长度足够围住其他树,砍掉哪些树.. 思路:先求要砍掉的哪些树,在求剩下的树求凸包,在判是否可行. ...

  6. POJ 1873 The Fortified Forest(枚举+凸包)

    Description Once upon a time, in a faraway land, there lived a king. This king owned a small collect ...

  7. POJ 1873 The Fortified Forest 凸包 二进制枚举

    n最大15,二进制枚举不会超时.枚举不被砍掉的树,然后求凸包 #include<stdio.h> #include<math.h> #include<algorithm& ...

  8. poj 1873 凸包+枚举

    The Fortified Forest Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 6198   Accepted: 1 ...

  9. Uva5211/POJ1873 The Fortified Forest 凸包

    LINK 题意:给出点集,每个点有个价值v和长度l,问把其中几个点取掉,用这几个点的长度能把剩下的点围住,要求剩下的点价值和最大,拿掉的点最少且剩余长度最长. 思路:1999WF中的水题.考虑到其点的 ...

随机推荐

  1. socketpair创建双向通信的管道(全双工通信)

    Linux下socketpair介绍: socketpair创建了一对无名的套接字描述符(只能在AF_UNIX域中使用),描述符存储于一个二元数组,例如sv[2] .这对套接字可以进行双工通信,每一个 ...

  2. 本地通知UILocalNotification

    1.增加一个本地推送 //设置20秒之后  ]; //chuagjian一个本地推送 UILocalNotification *noti = [[[UILocalNotification alloc] ...

  3. php析构方法

    析构方法说明: 1. 析构方法会自动调用 2. 析构方法主要用于销毁资源(比如释放数据库的链接,图片资源...销毁某个对象..); 析构函数会在到对象的所有的引用都被删除或者当对象被显示销毁时执行. ...

  4. JAVA_SE基础——2.环境变量的配置&测试JDK

    哈喽,利用晚上的空余时间再写篇心的~~~  谢谢大家 前一篇文章 JAVA_SE基础--JDK&JRE下载及安装http://blog.csdn.net/thescript_j/article ...

  5. KNN算法的代码实现

    # -*- coding: utf-8 -*-"""Created on Wed Mar 7 09:17:17 2018 @author: admin"&quo ...

  6. 第二章 初识JSP

    第二章   初识JSP 一.JSP简述 1.是JSP JSP是指在HTML中嵌入Java脚本语言.全称(Java Server Pages) 当用户通过浏览器访问Web应用时,使用JSP容器对请求的J ...

  7. Spark入门(1-3)Spark的重要概念

    1.什么是弹性分布式数据集? Spark提出了RDD(Resilient Distributed Datasets)这么一个全新的概念,RDD弹性分布式数据集是并行.容错的分布式数据结构:可以将RDD ...

  8. servlet filter中使用autowired无法注入

    问题: 我们为了避免未经授权的人直接通过url访问我们的页面,配置了如下filter <!-- 登录过滤器 --> <filter> <filter-name>se ...

  9. django Form组件 上传文件

    上传文件 注意:FORM表单提交文件要有一个参数enctype="multipart/form-data" 普通上传: urls: url(r'^f1/',views.f1), u ...

  10. Struts(二十二):国际化

    如何配置国际化资源文件? 1.Action范围资源文件:在Action类文件所在的路径建立名为ActionName_language_country.properties的文件: 2.包范围资源文件: ...