http://www.cnblogs.com/woodfish1988/archive/2008/09/08/1287166.html
今天终于学会用二进制的位运算来枚举。。。
#include<iostream>
#include<vector>
#include<map>
#include<stack>
#include<algorithm>
#include<queue>
#include<list>
#include<set>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<stdio.h>
#include<ctype.h>
#include<iomanip>
using namespace std;
#define LL long long
#define pi acos(-1)
#define N 20
#define INF 999999999
#define eps 1e-8
//****************************************
//poj1873
//Copyright@leolin. All rights reserved.
//****************************************
struct point
{
double x,y;
};
point res[N],stck[N],p0;
struct tree
{
point p;
double v,l;
}e[N];
int m;//凸包顶点数
int cut[N];
double cross(point a,point b,point c)
{
return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
double dis(point a,point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
bool cmp(point a,point b)
{
double t=cross(p0,a,b);
return t>0 || (t==0 && dis(p0,a)<dis(p0,b));
}
void convexHull(point p[],int n)
{
int i,j,k;
if(n<3)
{
for(i=0;i<n;i++)
stck[i]=p[i];
m=n;
return ;
}
for(k=0,i=0;i<n;i++)
if(p[i].y<p[k].y || (p[i].y==p[k].y && p[i].x<p[k].x))
k=i;
p0=p[k];
p[k]=p[0];
p[0]=p0;
sort(p+1,p+n,cmp);
stck[0]=p[0];
stck[1]=p[1];
int top=1;
for(i=2;i<n;i++)
{
while(top>1 && cross(stck[top-1],stck[top],p[i])<eps)
top--;
stck[++top]=p[i];
}
m=top+1;
}
double solve()
{
double ans=0.0;
for(int i=0;i<m-1;i++)
ans+=dis(stck[i],stck[i+1]);
ans+=dis(stck[0],stck[m-1]);
return ans;
}
int main()
{
// freopen("a.txt","r",stdin);
int n;
int ca=1;
while(scanf("%d",&n)&&n)
{
int i,j,k;
for(i=0;i<n;i++)
scanf("%lf%lf%lf%lf",&e[i].p.x,&e[i].p.y,&e[i].v,&e[i].l);
double minv=INF;
int tot=0;
double extra=0;
for(int bit=0;bit<(1<<n);bit++)
{
double val=0;
double len=0;
int cnt=0;
for(i=0;i<n;i++)
{
if(bit & (1<<i))//要砍的。位运算很强大!!!
{
val+=e[i].v;
len+=e[i].l;
}
else//保留的
{
res[cnt].x=e[i].p.x;
res[cnt].y=e[i].p.y;
cnt++;
}
}
if(val>minv)continue;
if(cnt==0 ||cnt==n)continue;
convexHull(res,cnt);
double L=solve();//printf("%.2f\n",L);
if(len>=L)
if(val<minv ||(val==minv && n-cnt<tot))
{
minv=val;
tot=0;
for(i=0;i<n;i++)
if(bit & (1<<i))
cut[tot++]=i+1;//要加1!!!
extra=len-L;
}
}
if(ca>1)printf("\n");
printf("Forest %d\n",ca++);
printf("Cut these trees:");
for(i=0;i<tot;i++)
{
printf(" %d",cut[i]);
}
printf("\n");
printf("Extra wood: %.2f\n",extra);
}
}