poj 3597 Polygon Division(递推)

10 篇文章 0 订阅
2 篇文章 0 订阅

【题目大意】:给出一个凸多边形,问将其划分成三角形和四边形有多少种划分方法。


【解题思路】:单单将这道题变成划分三角形,每个人无一例外的都会很快的反应到卡特兰数上去。

这道题的本质思路也跟卡特兰数相类似,也是一个递推或者说是dp的方法。

这里的思路引用了:http://hi.baidu.com/sunnyykn/blog/item/45b16d02cfdfb583d43f7c97.html


将n边形的顶点按顺时针或逆时针编号为1,2,3....n(n>=3),设T(n)为最终的结果,E(i,j)为i号顶点和j号顶点连成的对角线(1<=i<j<=n),我们定义T(2)=1.分两种情况讨论:
(1)边E(1,n)为划分后一个三角形的一条边。i为该三角形的另外一个顶点(2<=i<=n-1),因此,对角线E(1,i)和对角线E(i,n)将n边形分为1个i边形,1个由顶点(1,i,n)组成的三角形,1个(n-i+1)边形;这种情况下,问题规模缩小为小i边形,和(n-i+1)边形的。此时的种数为:
a=∑T(i)*T(n-i+1) (2<=i<=n-1)
(2)边E(1,n)为划分后一个四边形的一条边。i,j为该四边形的另外两个顶点(2<=i<=n-2,i+1<=j<=n-1)。1,n,i,j四个顶点将n边形分为1个i边形,1个j-i+1边形,1个n-j+1边形和该四边形。我们可以继续将i边形,j-i+1,n-j+1边形继续划分,规模也将继续缩小。此时的种数为:
b=∑∑T(i)*T(j-i+1)*T(n-j+1); (2<=i<=n-2,i+1<=j<=n-1)
故T(n)=a+b=∑T(i)*T(n-i+1)+∑∑T(i)*T(j-i+1)*T(n-j+1);
此时的时间复杂度为O(n^3),会TLE,我们可以将上述表达式写成以下形式以降低时间复杂度
U(n)=∑T(i)*T(n-i+1);(2<=i<=n-1)
T(n)=U(n)+∑T(i)*U(n-i+1);(2<=i<=n-2)

这样我们可以获得O(n^2).的做法。


这道题还有一个神奇的地方就是,它是用了unsigned long long的自爆形式来进行取模~当初第一次写的时候傻傻的写了个高精度,差点没挂在那里......


【代码】:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

unsigned long long u[5050],t[5050];

int main(){
    u[0]=u[1]=u[2]=1;
    t[0]=t[1]=t[2]=1;
  //  unsigned long long tmp=1;
    for (int i=3; i<=5000; i++){
        u[i]=0;
        for (int j=2; j<=i-1; j++){
            u[i]+=t[j]*t[i-j+1];
        }
        t[i]=u[i];
        for (int j=2; j<=i-2; j++){
           t[i]+=t[j]*u[i-j+1];
        }
    }
    for (int i=3; i<=5000; i++)cout << t[i] << endl;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值