KunKun的征途

明天的明天,你还会送我水晶之恋吗?

导航

[HDU 5135] Little Zu Chongzhi's Triangles (dfs暴搜)

Posted on 2014-12-03 23:29  西域小车  阅读(212)  评论(0)    收藏  举报

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5135

题目大意:给你n条边,选出若干条边,组成若干个三角形,使得面积和最大。输出最大的面积和。

 

先将边从小到大排序,这样前面的两条边加起来如果不大于第三条边就可以跳出,这是一个存在性条件。

dfs(int idx,int now,int cnt,int nowmax)代表我当前处理的是第idx条边,已经加入边集的有cnt条边,当前的边的长度和为now,组成的最大面积和为nowmax。

暴力枚举每个三角形,相加求出和,算最大的。

 

 1 #include <cstring>
 2 #include <string>
 3 #include <vector>
 4 #include <cstdio>
 5 #include <iostream>
 6 #include <algorithm>
 7 #include <queue>
 8 #include <cmath>
 9 using namespace std;
10 
11 int n;
12 int edge[20];
13 bool vis[20];
14 vector<int> edges;
15 double maxn;
16 
17 double getArea(int a,int b,int c){
18     double p = double(a+b+c) / 2;
19     return sqrt( p*(p-a)*(p-b)*(p-c) );
20 }
21 
22 void dfs(int idx,int now,int cnt,double nowsum){
23     if( edges.size()==3 ){
24         double area = getArea(edges[0],edges[1],edges[2]);
25         nowsum += area;
26         maxn = max(maxn,nowsum);
27         edges.clear();
28     }
29     for(int i=idx;i<n;i++) if(!vis[i]) {
30         if( cnt<2 ){
31             vis[i] = true;
32             edges.push_back(edge[i]);
33             dfs(idx+1,now+edge[i],cnt+1,nowsum);
34             vis[i] = false;
35             edges.pop_back();
36         } else if(cnt==2&&now>edge[i]){
37             vis[i] = true;
38             edges.push_back(edge[i]);
39             dfs(idx+1,0,0,nowsum);
40             vis[i] = false;
41             edges.pop_back();
42         } else if( now<=edge[i] ) break;
43     }
44 }
45 
46 int main(){
47     while( scanf("%d",&n)!=EOF ){
48 //        printf("n = %d\n",n);
49         if( n==0 ) break;
50 //        puts("*******");
51         for(int i=0;i<n;i++){
52             scanf("%d",&edge[i]);
53         }
54         sort(edge,edge+n);
55         edges.clear();
56         memset(vis,0,sizeof(vis));
57         maxn = 0.0;
58         dfs(0,0,0,0);
59         printf("%.2lf\n",maxn);
60     }
61     return 0;
62 }