解题思路:这道题看到数据量,想到应该搜索+剪枝应该可以过。。可是别人的A了,我的却超时了。。。
我用了一个mark[a][b],表示前两条边长度分别为a和b时,是否已经处理过,如果是的话就直接跳出。。。剩下的就是一个比较简单的搜索过程了,代码不难写,但是确实超时不可避免。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn = 45;
int n,len[maxn],s;
double half,ans;
bool vis[maxn],mark[maxn][maxn];
bool cmp(int a,int b)
{
return a < b;
}
void dfs(int cur,int a,int b,int dep)
{
if(mark[a][b] || mark[b][a]) return;
if(dep == 3){
int c = s - a - b;
mark[a][b] = mark[b][a] = true;
if(a + b <= c || b + c <= a || a + c <= b) return;
double area = half*(half-a)*(half-b)*(half-c);
if(area > ans) ans = area;
return;
}
for(int i = cur+1; i <= n; i++){
if(vis[i] == true) continue;
vis[i] = true;
if(dep == 1){
dfs(cur+1,a+len[i],b,dep);
dfs(0,a+len[i],b,dep+1);
}
else{
dfs(cur+1,a,b+len[i],dep);
dfs(0,a,b+len[i],dep+1);
}
vis[i] = false;
}
}
int main()
{
while(scanf("%d",&n)!=EOF){
s = 0;
for(int i = 1; i <= n; i++){
scanf("%d",&len[i]);
s += len[i];
}
half = s / 2.0;
sort(len+1,len+1+n,cmp);
memset(vis,false,sizeof(vis));
memset(mark,false,sizeof(mark));
ans = -1;
dfs(0,0,0,1);
if(ans < 0) printf("-1\n");
else printf("%d\n",(int)(sqrt(ans)*100));
}
return 0;
}
看了下别人的剪枝,确实比我拓展的节点要少,同样mark[i][a][b]表示第i条边时,最短边为a,次短边为b时,是否处理过。。。因为我自己写的mark[a][b]可能会出现重复的情况,因为a,b,c的大小关系并没有确定好,相同的三角形可能会出现三次,这样拓展出的新节点个数太多,会导致超时的。。。
#include <iostream>
#include <cmath>
using namespace std;
const int MAXN = 41;
int fence[MAXN];
bool mark[MAXN][MAXN * MAXN][MAXN * MAXN];
int N, s;
double hs;
void recur(int i, int a, int b, double &maxt)
{
if(a > s / 3 || mark[i][a][b])
{
return;
}
mark[i][a][b] = true;
if(i == N)
{
int c = s - a - b;
if(a > 0 && b > 0 && c > 0 && a <= b && b <= c && a + b > c)
{
double t = (hs - a) * (hs - b) * (hs - c);
if(t > maxt)
{
maxt = t;
}
}
return;
}
recur(i + 1, a + fence[i], b, maxt);
recur(i + 1, a, b + fence[i], maxt);
recur(i + 1, a, b, maxt);
}
int main()
{
cin>>N;
s = 0;
for(int i = 0; i < N; ++i)
{
cin>>fence[i];
s += fence[i];
}
hs = s * 1.0 / 2;
double maxt = -1;
recur(0, 0, 0, maxt);
if(maxt < 0)
{
cout<<"-1"<<endl;
}
else
{
cout<<(int)(sqrt(maxt * hs) * 100)<<endl;
}
return 0;
}