洛谷三角形牧场(随机化贪心)

奶牛建筑师Hei想要用N块不同长度的木板围成一个三角形牧场,使得面积最大。题目要求计算最大面积,并提供了一个可以接受的随机贪心算法解决方案。输入包括木板的数量和长度,输出是最大面积(乘以100并舍尾)。当无法构建三角形时,输出-1。给定的输入样例中,通过随机贪心算法构建的等边三角形边长为4,最大面积为692。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

三角形牧场
题目描述
和所有人一样,奶牛喜欢变化。它们正在设想新造型的牧场。奶牛建筑师Hei想建造围有漂亮白色栅栏的三角形牧场。她拥有N(3≤N≤40)块木板,每块的长度Li(1≤Li≤40)都是整数,她想用所有的木板围成一个三角形使得牧场面积最大。

请帮助Hei小姐构造这样的牧场,并计算出这个最大牧场的面积。

输入输出格式
输入格式:
第1行:一个整数N

第2…N+1行:每行包含一个整数,即是木板长度。

输出格式:
仅一个整数:最大牧场面积乘以100然后舍尾的结果。如果无法构建,输出-1。

输入输出样例
**输入样例#1: **
5
1
1
3
3
4
**输出样例#1: **
692
说明
样例解释:692=舍尾后的(100×三角形面积),此三角形为等边三角形,边长为4。

这道题正解是转化为二维 d p dp dp来判定当前的解是否存在,然而经过本蒟蒻的尝试,随机贪心是可以跑过的。

代码如下:

#include<bits/stdc++.h>
using namespace std;
int n,l[45],sum[5],ans=-1;
inline int sol(double a,double b,double c){
   
   
    if(
### P1284 三角形牧场 题目描述 奶牛们希望设计一种新的牧场形状——由漂亮的白色栅栏围成三角形牧场。建筑师 Hei 手中有 $n$ 木板每块木板长度整数值 $l_i$。她的目标是利用这些木板拼接出一个能够形成合法三角形的最大面积牧场。 #### 输入格式 输入的第一行为一个整数 $n$ ($3 \leq n \leq 15$),代表拥有的木板数量;第二行为 $n$ 个正整数 $l_1, l_2, ..., l_n$ ($1 \leq l_i \leq 10^6$),分别表示各木板长度。 #### 输出格式 如果无法构成任何三角形,则输出 `-1`;否则输出能组成的最大面积,保留两位小数。 --- ### 解法分析 此问题的核心在于如何通过给定的木板组合找到满足三角形条件的最佳方案并计算其面积。以下是两种主要方法: #### 方法一:动态规划 (DP) 定义状态 `dp[i][j]` 表示前 $i$ 条边中是否存在两条边分别为 $j$ 和 $c-j-k$ 的情况,其中 $c=\sum_{k=1}^{n}{l_k}$ 是总周长的一半[^2]。转移方程如下: ```cpp if ((j - l[i] >= 0 && dp[j - l[i]][k]) || (k - l[i] >= 0 && dp[j][k - l[i]])) dp[j][k] = true; ``` 最终判断是否能找到个符合条件的边 $(a,b,c)$ 并验证它们是否可构成三角形: ```cpp inline bool check(int a, int b, int c) { if (a + b > c && a + c > b && b + c > a) return true; return false; } check(i, j, c - i - j); ``` 一旦确认存在这样的边组合,即可应用 **海伦公式** 计算面积: $$ S = \sqrt{p(p-a)(p-b)(p-c)} $$ 其中 $ p = \frac{a+b+c}{2} $ 是半周长。 --- #### 方法二:搜索算法 另一种解法基于暴力搜索的思想,但由于直接穷举所有可能性会导致超时(TLE),因此需引入剪枝策略优化效率[^4]。具体实现步骤包括但不限于以下几个方面: - 对原始数组按升序排列; - 枚举当前尝试加入哪条边上; - 使用回溯技术逐步试探直至完成分配过程; - 结合均值不等式的理论依据进一步缩小候选范围,即倾向于让条边尽可能接近从而提升潜在最优解的概率。 下面是简化版伪代码展示这一逻辑框架: ```python def dfs(index, sideA, sideB, sideC): global maxArea # 边界处理与更新最佳结果记录 currentPerimeter = sideA + sideB + sideC semiPerimeter = currentPerimeter / 2 areaCandidate = sqrt(semiPerimeter*(semiPerimeter-sideA)*(semiPerimeter-sideB)*(semiPerimeter-sideC)) if isValid(sideA, sideB, sideC): if areaCandidate > maxArea: maxArea = areaCandidate # 继续探索剩余选项 for nextIndex in range(index+1, lengthOfPlanks): newLength = lengths[nextIndex] # 分配至不同边缘之一 dfs(nextIndex, sideA + newLength, sideB , sideC ) dfs(nextIndex, sideA , sideB + newLength, sideC ) dfs(nextIndex, sideA , sideB , sideC + newLength ) # 初始化调用入口函数 maxArea = -1 dfs(-1, 0, 0, 0) print("%.2f"%maxArea if maxArea != -1 else "-1") ``` 注意此处仅提供概念示意而非完整可用程序片段。 --- ### 海伦公式的实际运用实例 假设已知某组数据样本 $\{7, 9, 12\}$ 可成功构建有效三角形,则对应操作流程如下所示: 设 $s=(7+9+12)/2=14$ 代入得 $$ A=\sqrt{s(s−a)(s−b)(s−c)}=\sqrt{14(14−7)(14−9)(14−12)}≈26.83 $$ ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值