标签:style blog http color width 2014
题目大意:现在要用如图机器对一块钢板进行切割,给出切割路线经过的若干个点,问可以切割成多少种不同的形状,注意切割下的为一整块。
解题思路:
所以我们定义两条切割线分别为上线和下线,两条折线不能相交,dp[i][j]表示上线画到点i,下线画到点j的切割方法数。因为所给定得点都需要被切割,将点按照x排序,然后递推。
所以需要进行判断,绿线为需要判定的线,需要考虑到所有在上线的点[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;
}
uva 1425 - Metal(递推),布布扣,bubuko.com
标签:style blog http color width 2014
原文地址:http://blog.csdn.net/keshuai19940722/article/details/35994195