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); } }