HDU2050 折线分割平面 动态规划

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2050 


分析:首先我们来看一直线分割平面,直线分割平面时,每增加n个结点,就会增加n+1个平面,我们用f(n)来表示n条直线最多分割出的平面数,那么就有f(n)=f(n-1)+n;其中f(1)=2;即每新加一条直线,都使他和原先所有的直线都有交点,原先有n-1条直线,那么新加一条直线后,就会多出n-1+1即n个平面。或者我们也可以这样理解:当有n-1条直线时,平面最多被分成了f(n-1)个区域。则第n条直线要是切成的区域数最多,就必须与每条直线相交且不能有同一交点。这样就会得到n-1个交点。这些交点将第n条直线分为2条射线和n-2条线段。而每条射线和线段将以有的区域一分为二。这样就多出了2+(n-2)即n个区域。通向公式为f(n)=n(n+1)/2+1。

    现在我们来考虑折线的情况,每加一条折线,就增加了两条相交的直线,当画第n条折线时,前面已经存在n-1条折线(即2n-2条直线)了,第n条折线包含的这两条直线分别和前面2n-2条直线相交,然后这两条直线还有一个交点,交点数再加上1,然而,我们注意到,在折线上的这个交点并不会使分割的平面数变化,所以这个交点不能算进去。那么最后就有f(n)=f(n-1)+2*(2n-2)+1=f(n-1)+4n-3;进一步求得通项公式:f(n)=2*n*n-n+1。或者末尾这样理解:当n-1条折线时,区域数为f(n-1)。为了使增加的区域最多,则折线的两边的线段要和n-1条折线的边,即2*(n-1)条线段相交。那么新增的线段数为4*(n-1),射线数为2。但要注意的是,折线本身相邻的两线段只能增加一个区域。


递推实现代码如下:

#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
    int f[10001];
    int t,n,i;
    f[1]=2;
    for(i=2;i<=10000;i++)
      f[i]=f[i-1]+4*i-3;
    cin>>t;
    while(t--)
    {
        scanf("%d",&n);
        printf("%d\n",f[n]);
    }
    return 0;
}




通向公式实现代码如下:

#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
    int t,n;
    cin>>t;
    while(t--)
    {
        scanf("%d",&n);
        printf("%d\n",2*n*n-n+1);
    }
    return 0;
}




类似的,对于封闭图形分割平面和平面分割空间的情况,我们可以参考下面的链接:

http://blog.csdn.net/ac_gibson/article/details/46351673

你可能感兴趣的:(HDU2050 折线分割平面 动态规划)