题意:砍掉一些树,用来围剩下的树,要使能包围的请款下,剩下树的价值最大,
思路:二进制枚举所有可能的情况,用凸包找包围的最短长度。
#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;
}