zoukankan      html  css  js  c++  java
  • [APIO2016]划艇

    [APIO2016]划艇 

    总共只有2*n段。分段进行DP

    简单的方法是:

    外层枚举段数j,f[i]表示,当前枚举到j的时候,以(i,j)结尾(必须选择(i,j))的方案数,枚举一个f(p,1~j-1)进行转移

    连续一段j区间,有包括i一共有m个可以选择的学校,那么这里贡献的方案数就是:∑(1<=i<=m)C(len,i)*C(m-1,i)=C(l+m-1,m)等式考虑用网格图走来证明

    C可以预处理

    #include<bits/stdc++.h>
    #define reg register int
    #define il inline
    #define fi first
    #define se second
    #define mk(a,b) make_pair(a,b)
    #define numb (ch^'0')
    using namespace std;
    typedef long long ll;
    template<class T>il void rd(T &x){
        char ch;x=0;bool fl=false;
        while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
        for(x=numb;isdigit(ch=getchar());x=x*10+numb);
        (fl==true)&&(x=-x);
    }
    template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');}
    template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');}
    template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('
    ');}
    
    namespace Miracle{
    const int N=1003;
    const int mod=1e9+7;
    int n;
    int lo[N],hi[N],c[2*N],cnt;
    int C[N];
    int ad(int x,int y){
        return x+y>=mod?x+y-mod:x+y;
    }
    int mul(int x,int y){
        return (ll)x*y%mod;
    }
    int g[N];
    int inv[N];
    int main(){
        rd(n);
        inv[1]=1;
        for(reg i=2;i<=n;++i){
            inv[i]=mul(mod-mod/i,inv[mod%i]);
        }
        for(reg i=1;i<=n;++i){
            rd(lo[i]);rd(hi[i]);
            c[++cnt]=lo[i];c[++cnt]=hi[i]+1;
        }
        sort(c+1,c+cnt+1);
        cnt=unique(c+1,c+cnt+1)-c-1;
        for(reg i=1;i<=n;++i){
            lo[i]=lower_bound(c+1,c+cnt+1,lo[i])-c;
            hi[i]=lower_bound(c+1,c+cnt+1,hi[i]+1)-c;
        }
        g[0]=1;C[0]=1;
        // cout<<" cnt "<<cnt<<endl;
        // prt(lo,1,n);
        // prt(hi,1,n);
        for(reg j=1;j<cnt;++j){
            int len=c[j+1]-c[j];
            // cout<<" len "<<len<<" in "<<j<<endl;
            C[0]=len;
            for(reg i=1;i<=n;++i) C[i]=mul(C[i-1],mul(len+i,inv[i+1]));
            // cout<<" C ";prt(C,0,n);
            for(reg i=n;i>=1;--i){
                if(lo[i]<=j&&j<hi[i]){
                    int f=0,m=0;
                    for(reg p=i-1;p>=0;--p){
                        f=ad(f,mul(C[m],g[p]));
                        if(lo[p]<=j&&j<hi[p]) ++m;
                    }
                    g[i]=ad(g[i],f);
                    // cout<<" con "<<i<<" "<<f<<endl;
                }
            }
            // cout<<"gg "<<endl;
            // prt(g,1,n);
        }
        int ans=0;
        for(reg i=1;i<=n;++i) ans=ad(ans,g[i]);
        ot(ans);return 0;
    }
    
    }
    signed main(){
        Miracle::main();
        return 0;
    }
    
    /*
       Author: *Miracle*
    */
  • 相关阅读:
    Dephi XE 编译后执行文件的路径怎么改
    一名Delphi程序员的开发习惯
    Delphi AnimateWindow 用法 淡入淡出窗口
    Delphi开发DLL
    delphi 中配置文件的使用(*.ini)
    Delphi中根据分类数据生成树形结构的最优方法
    Delphi語法筆記
    2015年10月19日 做过的面试题(四)
    ios 客户端定位的3种方法
    常用开源镜像站整理android sdk manager
  • 原文地址:https://www.cnblogs.com/Miracevin/p/10777929.html
Copyright © 2011-2022 走看看