码迷,mamicode.com
首页 > 其他好文 > 详细

uva 1425 - Metal(递推)

时间:2014-07-01 08:23:17      阅读:274      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   width   2014   

题目链接:uva 1425 - Metal

题目大意:现在要用如图机器对一块钢板进行切割,给出切割路线经过的若干个点,问可以切割成多少种不同的形状,注意切割下的为一整块。

解题思路:

  • 由图可以得知,两条切割线是不可以相交的
  • 由题目描述可知,所有点的x坐标是不会重复的
  • 机器不会回退,也就是说钢板是朝一个方向移动的,这样的切割路线是不会产生的
    bubuko.com,布布扣

所以我们定义两条切割线分别为上线和下线,两条折线不能相交,dp[i][j]表示上线画到点i,下线画到点j的切割方法数。因为所给定得点都需要被切割,将点按照x排序,然后递推。

  • dp[i][j]+=dp[i?1][j]
  • dp[j][i]+=dp[j][i?1]
    因为点i-1的横坐标肯定大于j,所以肯定可以转移。
  • dp[i][i?1]+=dp[j][i?1]
  • dp[i?1][i]+=dp[i?1][j]
    这种情况下,j的横坐标是小于x-1的横坐标,所以有可能发生相交的情况。(红线为上线,蓝线为下线)
    bubuko.com,布布扣

所以需要进行判断,绿线为需要判定的线,需要考虑到所有在上线的点[j+1,i?1](紫色点),均要在对应横坐标相同的褐色点上面,同理判断上线的时候要在下面。

bubuko.com,布布扣

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 55;
const double eps = 1e-9;

struct point {
    double x, y;
}p[N];

int n, dp[N][N];

bool cmp (const point& a, const point& b) {
    return a.x < b.x;
}

bool judge (int a, int b, double d, int key) {

    for (int i = a + 1; i <= b; i++) {
        double tmp = p[a].y + d * (p[i].x - p[a].x);

        if (key == 0 && tmp - p[i].y > -eps)
            return false;

        if (key == 1 && tmp - p[i].y < eps)
            return false;
    }
    return true;
}

int solve () {
    memset(dp, 0, sizeof(dp));

    dp[1][0] = dp[0][1] = 1;

    for (int i = 2; i < n-1; i++) {

        int u = i-1;
        for (int j = 0; j < u; j++) {
            dp[i][j] += dp[u][j];
            dp[j][i] += dp[j][u];

            double xi = p[i].x - p[j].x;
            double yi = p[i].y - p[j].y;

            double d = yi / xi;

            if (judge(j, u, d, 0))
                dp[u][i] += dp[u][j];

            if (judge(j, u, d, 1))
                dp[i][u] += dp[j][u];
        }
    }

    /*
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {

            if (dp[i][j] && (i == n-2 || j == n-2)) {
                printf("%d %d: %d\n", i, j, dp[i][j]);
            }
        }
    }
    */

    int ans = 0, u = n-1;
    for (int i = 0; i < u-1; i++) {

        double xi = p[u].x - p[i].x;
        double yi = p[u].y - p[i].y;

        double d = yi / xi;

        if (judge(i, u-1, d, 0))
            ans += dp[u-1][i];

        if (judge(i, u-1, d, 1))
            ans += dp[i][u-1];
    }
    return ans;
}

int main () {
    int cas;
    scanf("%d", &cas);

    while (cas--) {

        scanf("%d", &n);
        for (int i = 0; i < n; i++)
            scanf("%lf%lf", &p[i].x, &p[i].y);
        sort(p, p + n, cmp);

        printf("%d\n", solve());
    }
    return 0;
}

uva 1425 - Metal(递推),布布扣,bubuko.com

uva 1425 - Metal(递推)

标签:style   blog   http   color   width   2014   

原文地址:http://blog.csdn.net/keshuai19940722/article/details/35994195

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!