zoukankan      html  css  js  c++  java
  • 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
    ",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("
    ");
    		printf("Extra wood: %0.2lf
    ",anslen);
    		printf("
    ");
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    三年Android开发经验,挥泪整理字节跳动、微软中国凉经,你不看看吗?
    App怎么做才能永不崩溃
    做了八年的Android开发,谁不是一边崩溃,一边默默坚守!
    阿里员工年年绩效A,晒出收入后感叹:996虽然痛苦,发钱时候真香
    2021阅读书单
    不动产测绘概念
    Elasticsearch 集成
    Elasticsearch 环境
    Elasticsearch 优化
    Elasticsearch入门
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/3883609.html
Copyright © 2011-2022 走看看