洛谷 P1284 三角形牧场

2025-02-12T20:48:12

url: https://www.luogu.com.cn/problem/P1284

tag:
动态规划,贪心,背包DP

思路:
f[k][i][j] 来表示前k块木板能否组成三角形。所以状态转移方程为:
f[k][i][j] = f[k - 1][i - a[k]][j] || f[k - 1][i][j - a[k]] || f[k][i][j]
因为转移时只跟 f[k - 1][][] 层的数据有关,所以可以用类似01背包问题的方式来简化掉这一维。初始化 f[0][0] = 1 之后对于每一个可能的结果判断是否为合法三角形,然后计算面积更新最大值即可。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 50;
int n, sum;
int a[N];
bool f[N * N][N * N];
long long ans;
bool check(int a, int b, int c)
{
    return a + b > c && a + c > b && b + c > a;
}
double resolue(int a, int b, int c)
{
    double p = (a * 1.0 + b + c) / 2;
    return sqrt(p * (p - a) * (p - b) * (p - c));
}
int main()
{
    cin >> n;
    for (int i = 1; i <= n; i ++)
    {
        cin >> a[i];
        sum += a[i];
    }
    f[0][0] = 1;
    for (int k = 1; k <= n; k ++)
        for (int i = sum / 2; i >= 0; i --)
            for (int j = sum / 2; j >= 0; j --)
            {
                if (i - a[k] >= 0 && f[i - a[k]][j]) f[i][j] = 1;
                if (j - a[k] >= 0 && f[i][j - a[k]]) f[i][j] = 1;
            }
    double res = -1;
    for (int i = sum / 2; i > 0; i --)
        for (int j = sum / 2; j > 0; j --)
        {
            if (!f[i][j]) continue;
            if (!check(i, j, sum - i - j)) continue;
            res = max(res, resolue(i, j, sum - i - j));
        }
    if (res == -1) cout << -1 << endl;
    else cout << (long long)(res * 100) << endl;
    return 0;
}
当前页面是本站的「Baidu MIP」版。发表评论请点击:完整版 »