洛谷P1284三角形牧场题解

题目简单描述:有n个长度一定的木棍,问这些木棍组成的三角形的最大面积为多少?

题目链接:三角形牧场 - 洛谷

我来分享一下搜索的解法,虽然正解是dp(bushi)。首先暴力搜索的思路就是我们枚举每一条木棍看把他加到三条边的那一条边中,但是这样显然会tle的。所以我们先考虑第一个优化就是进行排序,排序后的序列我们保证他是一个有序序列,在序列有序的情况下我们是从小到大排序,所以我们在进行了多次递归之后我们在回溯的时候是优先对于较大的边进行调整所以可以较为优先的搜到答案,可是我们发现这样做只有56分,那么我们继续考虑优化三角形成立的条件为两边之和大于第三边,并且我们可以知道这个三角形的周长为定值所以我们根据均值不等式不能得出在三边的边长相近的时候会出现最大的答案,所以我们就按照尽量使他们的三边相等为第一关键字来安排搜索。

显然我们是不可能搜完的但是我们可以在1s之内把答案搜到就成功了。

code:

#include <bits/stdc++.h>
using namespace std;
int qaq[100010];
int maxx = -1;
int a;
int t1,t2;
int calc(int l1,int l2,int l3) {      //海伦公式计算
    double faq = (double)(l1 + l2 + l3) / 2;
    double ans = sqrt(faq * (faq - l1) * (faq - l2) * (faq - l3)) * 100;   
    return (int)ans;
}
void dfs(int num,int l1,int l2,int l3) {    //搜索部分
    t2 = clock(); 
    if(t2 - t1 > 900000) {    //计算程序运行的时间在1s之内输出答案。
        cout<<maxx;
        exit(0);
    }
    if(num == a + 1) {      //完成了一次搜索对答案进行统计。
        if(l1 + l2 <= l3)
            return;
        if(l1 + l3 <= l2)
            return;
        if(l3 + l2 <= l1)
            return;
        maxx = max(calc(l1,l2,l3),maxx);
    }
    else {
        if(l1 <= l2 && l1 <= l3) {      //我们开始贪心 尽量使他们的三条边相近。
            dfs(num + 1,l1 + qaq[num],l2,l3);
            if(l2 <= l3) {    //当前l1为最小的我们向l1上加边。再判断l2和l3的大小。
                dfs(num + 1,l1,l2 + qaq[num],l3);
                dfs(num + 1,l1,l2,l3 + qaq[num]);
            }
            else {
                dfs(num + 1,l1,l2,l3 + qaq[num]);
                dfs(num + 1,l1,l2 + qaq[num],l3);
            }
        }
        if(l2 <= l1 && l2 <= l3) {     //同理如上  当前l2是最小的。优先搜索l2
            dfs(num + 1,l1,l2 + qaq[num],l3);
            if(l1 <= l3) {
                dfs(num + 1,l1 + qaq[num],l2,l3);
                dfs(num + 1,l1,l2,l3 + qaq[num]);
            }
            else {
                dfs(num + 1,l1,l2,l3 + qaq[num]);
                dfs(num + 1,l1 + qaq[num],l2,l3);
            }
        }
        if(l3 <= l2 && l3 <= l1) {  //同理
            dfs(num + 1,l1,l2,l3 + qaq[num]);
            if(l1 <= l2) {
                dfs(num + 1,l1 + qaq[num],l2,l3);
                dfs(num + 1,l1,l2 + qaq[num],l3);
            }
            else {
                dfs(num + 1,l1,l2 + qaq[num],l3);
                dfs(num + 1,l1 + qaq[num],l2,l3);
            }
        }

    }
}
int main() {
    t1 = clock();
    cin>>a;
    for(int i = 1;i <= a;i ++) {
        cin>>qaq[i];
    }
    sort(qaq + 1,qaq + 1 + a);
    dfs(1,0,0,0);
    cout<<maxx;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值