Codeforces 437E The Child and Polygon

http://codeforces.com/problemset/problem/437/E

题意:求一个多边形划分成三角形的方案数

思路:区间dp,每次转移只从一个方向转移(L,R连线的某一侧),能保证正确。

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#define ll long long
const ll Mod=1000000007;
ll f[5005][5005];
struct Point{
    double x,y;
    Point(){}
    Point(double x0,double y0):x(x0),y(y0){}
}p[500005];
Point operator -(Point p1,Point p2){
    return Point(p1.x-p2.x,p1.y-p2.y);
}
double operator *(Point p1,Point p2){
    return p1.x*p2.y-p1.y*p2.x;
}
int read(){
    int t=0,f=1;char ch=getchar();
    while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
    return t*f;
}
ll solve(int l,int r){
    if (f[l][r]!=-1) return f[l][r];
    if (l>r) return f[l][r]=0;
    if (l+1==r) return f[l][r]=1;
    f[l][r]=0;
    for (int i=l+1;i<r;i++){
        if ((p[r]-p[l])*(p[i]-p[l])<0) 
         (f[l][r]+=(solve(l,i)*solve(i,r))%Mod)%=Mod;
    }
    return f[l][r];
}
int main(){
    int n=read();
    for (int i=1;i<=n;i++) p[i].x=read(),p[i].y=read();
    for (int i=1;i<=n;i++)
     for (int j=1;j<=n;j++)
      f[i][j]=-1;
    double res=0;
    p[n+1]=p[1];
    for (int i=1;i<=n;i++)
     res+=p[i]*p[i+1];
    if (res<0){
     for (int i=1;i<=n/2;i++) std::swap(p[i],p[n-i+1]);
    } 
    printf("%lld
",solve(1,n));
}
原文地址:https://www.cnblogs.com/qzqzgfy/p/5666244.html