题目链接: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 }
[HDU 5135] Little Zu Chongzhi's Triangles (dfs暴搜)
时间: 2024-10-02 07:23:45