题意:砍掉一些树,用来围剩下的树,要使能包围的请款下,剩下树的价值最大,
思路:二进制枚举所有可能的情况,用凸包找包围的最短长度。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> using namespace std; const int N = 19; const double EPS = 1e-12; struct cpoint{ double x,y; int I; double len,val; void get(){scanf("%lf%lf%lf%lf",&x,&y,&val,&len);} cpoint(double a,double b){x=a,y=b;} cpoint(){} bool operator<(const cpoint t) const{ return y<t.y||(y==t.y&&x<t.x); } }; double dist(cpoint a,cpoint b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } double x_mult(cpoint a,cpoint b,cpoint c){ return (a.x-c.x)*(b.y-c.y)-(a.y-c.y)*(b.x-c.x); } int n; int cmp(const cpoint a,const cpoint b){ return a.y<b.y||(a.y==b.y&&a.x<b.x); } cpoint re[N],tu[N]; int tmp[N]; double ans ,relen, Val; int tans; bool visit[N]; int granham(cpoint p[],int s,cpoint r[]){ int i,len,top=1; sort(p,p+s,cmp); r[0] = p[0];r[1] = p[1];r[2] = p[2]; if(s<3) return s; for(i=2;i<s;i++){ while(top&&x_mult(p[i],r[top],r[top-1])>EPS) top--; r[++top] = p[i]; } len = top;r[++top] = p[s-2]; for(i=s-3;i>=0;i--){ while(top!=len&&x_mult(p[i],r[top],r[top-1])>EPS) top--; r[++top] = p[i]; } return top; } void solve(int m) { memset(visit,0,sizeof(visit)); double ret=0; int trees=0,cnt=0; relen = 0; cpoint p[N]; for(int i=0;i<n;i++) if(m&(1<<i)) { visit[i] = true; relen +=re[i].len; trees++; }else p[cnt++] = re[i],ret+=re[i].val; int k = granham(p,cnt,tu); double c=0; if(k==2) c=2*dist(tu[0],tu[1]); else if(k<=1) c = 0; else for(int i=0;i<k;i++) c+=dist(tu[i],tu[i+1]); if(relen>=c) { if(Val<ret) { Val=ret; ans = relen-c; tans = trees; int k=0; for(int i=0;i<n;i++) if(visit[i]) tmp[k++] = re[i].I; } } } int main() { freopen("in.txt","r",stdin); int T = 1; while(~scanf("%d",&n)&&n) { Val = -1; for(int i=0;i<n;i++) re[i].get(),re[i].I = i+1; sort(re,re+n); ans = 1e20;tans = 100; for(int i=0;i<(1<<n);i++) solve(i); printf("Forest %d\n",T++); printf("Cut these trees:"); sort(tmp,tmp+tans); for(int i=0;i<tans;i++) printf(" %d",tmp[i]); printf("\n"); printf("Extra wood: %.2lf\n\n",ans); } return 0; }