首页 > 代码库 > POJ 1873
POJ 1873
按位枚举,按最小价值,最小砍掉树剪枝就好了。
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;const int MAXN=20;const int inf=190000000;int n,l;int st[MAXN],stop,cnt;int ans[MAXN];bool cut[MAXN];struct point{ int x,y; int len,val; int num;}p[MAXN];int ansV,ansC;double anslen;bool cmp(point A,point B){ if(A.y<B.y) return true; else if(A.y==B.y){ if(A.x<B.x) return true; } return false;}bool cmp1(int a,int b){ if(a<b) return true; return false;}bool multi(point a,point b,point c){ return (a.x-c.x)*(b.y-c.y)-(a.y-c.y)*(b.x-c.x)<=0;}double dist(point a, point b){ return sqrt((a.x-b.x)*(a.x-b.x)*1.0+(a.y-b.y)*(a.y-b.y)*1.0);}double for_len(){ if(cnt==1) return 0; double res=0; for(int i=1;i<cnt;i++) res+=dist(p[ans[i]],p[ans[i-1]]); return (res);}void slove(){ stop=0; cnt=0; int choice=0; int be; for(int i=0;i<n;i++){ if(!cut[i]){ st[stop++]=i; choice++; } if(choice==2){ be=i; break; } } if(choice<2){ cnt=1; return ; } for(int i=be+1;i<n;i++){ if(cut[i]) continue; while(stop>1&&multi(p[st[stop-1]],p[i],p[st[stop-2]])) stop--; st[stop++]=i; } for(int i=0;i<stop;i++){ ans[cnt++]=st[i]; } stop=0; choice=0; for(int i=n-1;i>=0;i--){ if(!cut[i]){ st[stop++]=i; choice++; } if(choice==2){ be=i; break; } } for(int i=be-1;i>=0;i--){ if(cut[i]) continue; while(stop>1&&multi(p[st[stop-1]],p[i],p[st[stop-2]])) stop--; st[stop++]=i; } for(int i=0;i<stop;i++) ans[cnt++]=st[i];}int main(){ int cas=0; while(scanf("%d",&n)!=EOF){ if(n==0) break; cas++; for(int i=0;i<n;i++){ scanf("%d%d%d%d",&p[i].x,&p[i].y,&p[i].val,&p[i].len); p[i].num=i+1; } sort(p,p+n,cmp); ansV=inf; int tmpV; int tmpC; double len; int CUT=inf; for(int i=1;i<(1<<n);i++){ tmpV=0; tmpC=0; len=0; memset(cut,false,sizeof(cut)); for(int k=0;k<n;k++){ if((1<<k)&i){ cut[k]=true; tmpV+=p[k].val; tmpC++; len+=p[k].len; } } if(tmpV<ansV){ slove(); double res=for_len(); if(res<=len){ CUT=tmpC; ansV=tmpV; ansC=i; anslen=len*1.0-res; } } else if(tmpV==ansV){ if(CUT>tmpC){ slove(); double res=for_len(); if(res<=len){ CUT=tmpC; ansV=tmpV; ansC=i; anslen=len*1.0-res; } } } } printf("Forest %d\n",cas); printf("Cut these trees:"); cnt=0; for(int k=0;k<n;k++) if((1<<k)&ansC){ st[cnt++]=p[k].num; } sort(st,st+cnt,cmp1); for(int i=0;i<cnt;i++) printf(" %d",st[i]); printf("\n"); printf("Extra wood: %0.2lf\n",anslen); printf("\n"); } return 0;}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。