zoukankan      html  css  js  c++  java
  • BZOJ 2087: [Poi2010]Sheep

    Description

    (n)个顶点,(k)个点,问有多少三角剖分方案满足任意一个三角内都有偶数个点,(n leqslant 6 imes 10^2,kleqslant 2 imes 10^4).

    Solution

    极角排序+DP.

    枚举顶点,然后将点按照与这个点形成向量的极角排序,这样可以和其他点形成的三角形是否合法,也就是这一部分一定要有偶数个点才行.

    然后就是三角剖分的DP了,(f[i][j]) 表示(i,j)之间的顶点有多少种剖分方案,然后划分成两部分,来做,记搜会好写些.

    复杂度(O(nklogk+n^3))

    Code

    /**************************************************************
        Problem: 2087
        User: BeiYu
        Language: C++
        Result: Accepted
        Time:7936 ms
        Memory:4756 kb
    ****************************************************************/
     
    #include <bits/stdc++.h>
    using namespace std;
     
    #define mpr make_pair
    #define x first
    #define y second
    typedef pair< int,int > pr;
    const int N = 650;
    const int M = 2e4+50;
     
    pr operator - (const pr &a,const pr &b) { return mpr(a.x-b.x,a.y-b.y); }
    int operator * (const pr &a,const pr &b) { return a.x*b.y-a.y*b.x; }
    inline int in(int x=0,char ch=getchar(),int v=1) {
        while(ch>'9' || ch<'0') v=(ch=='-'?-1:v),ch=getchar();
        while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
        return x*v; }
     
    int n,k,m;
    pr B,r[N],p[M];
    int f[N][N],g[N][N];
     
    void out(pr a) { cout<<a.x<<" "<<a.y<<endl; }
    int cmp(const pr &a,const pr &b) { return (a-B)*(b-B)<0; }
    int DFS(int l,int r) {
        if(l==r || l+1==r) return f[l][r]=1;
        if(~f[l][r]) return f[l][r];
        f[l][r]=0;
        for(int i=l+1;i<r;i++) f[l][r]=(f[l][r]+DFS(l,i)*DFS(i,r)*g[l][i]*g[i][r]%m)%m;
        return f[l][r];
    }
    int main() {
    //  freopen("in.in","r",stdin);
        n=in(),k=in(),m=in();
        for(int i=1;i<=n;i++) {
            int x=in(),y=in();
            r[i]=mpr(x,y);
        }
        for(int i=1;i<=k;i++) {
            int x=in(),y=in();
            p[i]=mpr(x,y);
        }
        for(int i=1;i<=n;i++) {
            B=r[i];
            sort(p+1,p+k+1,cmp);
            int s=1;
            for(int j=i+1;j<=n;j++) {
                while(s<=k && (r[j]-B)*(p[s]-B)>0) s++;
                g[i][j]=(s&1)&&((p[s]-B)*(r[j]-B)!=0);
            }
        }
    /*  for(int i=1;i<=n;i++) {
            for(int j=i+1;j<=n;j++) {
                cout<<g[i][j]<<" ";
            }cout<<endl;
        }*/
        memset(f,0xff,sizeof(f));
        cout<<DFS(1,n)<<endl;
    /*  for(int i=1;i<=n;i++) {
            for(int j=i+1;j<=n;j++) {
                cout<<f[i][j]<<" ";
            }cout<<endl;
        }*/
        return 0;
    }
    /*
    5 4 10
    5 5
    3 0
    -1 -1
    -3 4
    1 10
    1 0
    -1 0
    1 6
    -2 5
    */
    
  • 相关阅读:
    您认为在测试人员同开发人员的沟通过程中,如何提高沟通的效率和改善沟通的效果?维持测试人员同开发团队中其他成员良好的人际关系的关键是什么?
    redis和jedis的用法,区别
    Jedis实现多种功能总结
    Druid简单介绍
    Svn与Git的区别
    SVN的一些基本概念(学前了解)
    Redis-cli 的功能
    postman的使用方法
    Spring Boot 有哪些优点?
    Redis中的常用命令哪些?
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/6327392.html
Copyright © 2011-2022 走看看