您的位置:首页 > 其它

UVA 811 - The Fortified Forest(凸包)

2014-06-27 16:08 351 查看
题目:The Fortified Forest

题意:二维平面上有n棵树,每棵树用一个点(x,y)表示,同时还有树自身的价值v以及用这棵树造栅栏的长度l。

现在要用其中一些树来当材料建造栅栏将剩下的树围起来,要求当材料的树的价值应该最小,如果多种情况符合,则取个数最少那个。

要求输出用作材料的树的编号以及造完栅栏后剩下的材料长度。

因为n<=15,所以可以直接枚举要砍的树,计算出砍下的树的总长度len,然后对剩下的点求凸包,计算凸包的周长used,如果len>=used说明当前方案可行,根据题目要求进行选择即可。

#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
const int inf = 0x7fffffff;
const double eps = 1e-8;
struct Point{
double x, y;
Point(){}
Point(double x, double y):x(x),y(y){}
bool operator < (const Point &tmp)const{
return x<tmp.x || (fabs(x-tmp.x)<eps&&y<tmp.y);
}
Point operator + (Point A){
return Point(x+A.x, y+A.y);
}
Point operator - (Point A){
return Point(x-A.x, y-A.y);
}
};
double dis(Point &A, Point &B){
return sqrt((A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y));
}
double det(Point A, Point B){
return A.x*B.y - A.y*B.x;
}
int n, v[20], l[20];
Point p[20];
vector<Point> V;
Point ch[20];
double ex, used;
double ConvexHull(){//返回凸包周长
int m = 0;
sort(V.begin(), V.end());
for(int i=0; i<V.size(); i++){
while(m>1 && det(ch[m-1]-ch[m-2], V[i]-ch[m-2])<=0)	m--;
ch[m++] = V[i];
}
int k = m;
for(int i=V.size()-2; i>=0; i--){
while(m>k && det(ch[m-1]-ch[m-2], V[i]-ch[m-2])<=0)	m--;
ch[m++] = V[i];
}
double res = 0;
for(int i=0; i<m-1; i++){
res += dis(ch[i], ch[i+1]);
}
return res;
}
int main(){
int ct = 0;
while(~scanf("%d", &n) && n){
if(ct)	puts("");
for(int i=0; i<n; i++){
scanf("%lf %lf", &p[i].x, &p[i].y);
scanf("%d %d", v+i, l+i);
}
int ans=inf, st, cnt, tmp, len;
for(int i=1; i<(1<<n); i++){
V.clear();
tmp = 0;
len = 0;
for(int j=0; j<n; j++){
if(i&(1<<j)){
tmp += v[j];
len += l[j];
}
else{
V.push_back(p[j]);
}
}
//这里做个剪枝,如果当前方案就算可行也不比当前优的话,则忽略。
if(tmp>ans || (tmp==ans && (n-V.size())>=cnt))	continue;
used = ConvexHull();
if(len>=used){
ans = tmp;
cnt = n-V.size();
st = i;
ex = len - used;
}
}
printf("Forest %d\n", ++ct);
printf("Cut these trees:");
for(int j=0; j<n; j++){
if(st&(1<<j))	printf(" %d", j+1);
}
puts("");
printf("Extra wood: %.2lf\n", ex);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: