hdu 5135 Little Zu Chongzhi's Triangles(分组dp)

来源:互联网 发布:被淘宝店家骚扰怎么办 编辑:程序博客网 时间:2024/04/29 09:07

题意:给n条边,要求用其中的某些边组成三角形,每条边只能用一次,问最后拼成的三角形面积总和最大是多少.


解析:开始的时候理解错题目要求了,无脑暴力了一段.之后想到dp,因为要把一堆东西分成一组一组,求每一种分法中的最优,所以就姑且叫他分组dp吧.(...)


首先将边按从小到大排序,保证每一个可拼的三角形的状态都能访问到.

接着将n条边分组,n条边最多可以拼出n / 3组三角形.

然后 dp[i][j] 第一维表示第i组,第二维表示第j条边, 则状态转移方程为:

    dp[i][j] = max(dp[i][j - 1] , dp[i - 1][j - 3] + area(a[j - 2], a[j - 1], a[j]))

具体意思是第j条边用不用,如果第j条边不用,则状态为上一组上一条边的状态:dp[i][j - 1];

如果第j条边用,则状态为上一组去掉上三边的状态加这一组三条边组成的面积:dp[i - 1][j - 3] + area(a[j - 2], a[j - 1], a[j])

需要注意的是判断三边能否组成三角形和末状态,因为 z=n / 3 向下取整,所以第z组<=.


代码:

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#define LL long longusing namespace std;const int maxn = 12 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = 4 * atan(1.0);const double ee = exp(1.0);double a[maxn];double dp[maxn][maxn];bool is_ok(double x, double y, double z){    if ((x + y > z && fabs(x - y) < z) && (x + z > y && fabs(x - z) < y) && (y + z > x && fabs(y - z) < x))        return true;    return false;}double area(double x, double y, double z)//Hero's formula{    double p = (x + y + z) / 2.0;    double s = sqrt(p * (p - x) * (p - y) * (p - z));    return s;}int main(){#ifdef LOCAL    freopen("in.txt", "r", stdin);#endif // LOCAL    int n;    while (scanf("%d", &n) && n)    {        for (int i = 1; i <= n; i++)        {            scanf("%lf", &a[i]);        }        sort(a + 1, a + n + 1);        memset(dp, 0, sizeof(dp));        int z = n / 3;        for (int j = 3; j <= n; j++)        {            for (int i = 1; i <= z; i++)            {               // if (3 * i <= j)                //{                    if (is_ok(a[j - 2], a[j - 1], a[j]))                    {                        double t = area(a[j - 2], a[j - 1], a[j]);                        if (dp[i - 1][j - 2] + t > dp[i][j - 1])                            dp[i][j] = dp[i - 1][j - 3] + area(a[j - 2], a[j - 1], a[j]);                        else                            dp[i][j] = dp[i][j - 1];                    }                    else                    {                        dp[i][j] = dp[i][j - 1];                    }               // }            }        }        printf("%.2lf\n", dp[z][n]);    }    return 0;}


0 0
原创粉丝点击