首页 > 代码库 > uva 1425 - Metal(递推)
uva 1425 - Metal(递推)
题目链接:uva 1425 - Metal
题目大意:现在要用如图机器对一块钢板进行切割,给出切割路线经过的若干个点,问可以切割成多少种不同的形状,注意切割下的为一整块。
解题思路:
- 由图可以得知,两条切割线是不可以相交的
- 由题目描述可知,所有点的x坐标是不会重复的
- 机器不会回退,也就是说钢板是朝一个方向移动的,这样的切割路线是不会产生的
所以我们定义两条切割线分别为上线和下线,两条折线不能相交,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的横坐标,所以有可能发生相交的情况。(红线为上线,蓝线为下线)
所以需要进行判断,绿线为需要判定的线,需要考虑到所有在上线的点[j+1,i?1](紫色点),均要在对应横坐标相同的褐色点上面,同理判断上线的时候要在下面。
#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;
}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。