poj 1873 The Fortified Forest

版权声明:欢迎复制!!! https://blog.csdn.net/qq_37493070/article/details/81782953

地址: 传送门在此

题意

给你n个树,给你每个树的坐标 x,y 还有 价值v 每个点有一个长度l ,你需要选几颗树砍了做围栏把剩下的树围起来,输出价值最小的方案,和剩下的木板,如果存在多个相同的价值,取数量最小的

做法

n<15 ,可以直接暴力枚举,用二进制表示每一种状态 , vector 会超时

代码

//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm> 
using namespace std;
#define ll long long
#define rd(a) scanf("%d",&a)
#define rld(a) scanf("%lld",&a)
#define rs(a) scanf("%s",a)
#define me(a,b) memset(a,b,sizeof(a))
#define pb(a)  push_back(a)
const ll maxn=3e5+10;
const ll mod =1e9+7;
const ll inf =0x3f3f3f3f;
const double PI=acos(-1);
struct paint{
    int x;
    int y;
    paint(){} 
    paint(int xx,int yy):x(xx),y(yy){}
    bool friend operator <(const paint &a,const paint &b){
        if(a.x==b.x) return a.y<b.y;
        return a.x<b.x;
    }
    bool friend operator ==(const paint &a,const paint &b){
        return a.x==b.x&&a.y==b.y;
    }
    paint friend operator -(const paint &a,const paint &b){
        return paint(a.x-b.x,a.y-b.y);
    }
};
int cross(paint a,paint b){
    return a.x*b.y-b.x*a.y;
}
double dis(paint a,paint b){
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
paint  w[30];
int Andrew(vector<paint>p){
    int n=p.size();
    sort(p.begin(),p.end());
    int m=0;

    for(int i=0;i<n;i++)
    {
        while(m>1&&cross(w[m-1]-w[m-2],p[i]-w[m-2])<=0) m--;
        w[m++]=p[i];
    }
    int o=m;
    for(int i=n-2;i>=0;i--){
        while(m>o&&cross(w[m-1]-w[m-2],p[i]-w[m-2])<=0) m--;
        w[m++]=p[i];
    }
    if(n>1) m--;
    return m;

}
paint p[30];
int v[30];
int len[30];
int main(){
    int n;
    int tt=1;
    while(~rd(n)&&n){
        for(int i=0;i<n;i++)
        {
            rd(p[i].x),rd(p[i].y),rd(v[i]),rd(len[i]);

        }
        double minn=inf;
        double minn_s=inf;
        int minn_size=n;
        int jl=-1;
        vector<paint>q;
        for(int i=1;i<(1<<n);i++){
            double ans_len=0;
            double ans_v=0;
            q.clear();
            for(int j=0;j<n;j++){
                if(i&(1<<j)) q.pb(p[j]);
                else ans_len+=len[j],ans_v+=v[j];
            }
            int siz=n-q.size();     
            int m=Andrew(q);
            double ans_lg=dis(w[0],w[m-1]);; 
            for(int j=1;j<m;j++){
                ans_lg+=dis(w[j],w[j-1]);               
            }
            if(ans_lg<=ans_len&&ans_v<minn){
                minn=ans_v;
                minn_s= ans_len-ans_lg;
                jl=i;
                minn_size=siz;
            }
            else if(ans_lg<=ans_len&&ans_v==minn&&siz<minn_size){
                minn=ans_v;
                minn_s= ans_len-ans_lg;
                jl=i;
                minn_size=siz;

            }
        }
        printf("Forest %d\nCut these trees:",tt++);
        int i=1;

         for(int j=0;j<n;j++){
                if(!(jl&(1<<j))) printf(" %d",j+1);
            }
        printf("\nExtra wood: %.2f\n\n",minn_s);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37493070/article/details/81782953