zoukankan      html  css  js  c++  java
  • LOJ#2567. 「APIO2016」划艇 离散化+DP

    运用到了 NOI2019 机器人那道题的技巧.    

    考虑对区间进行离散化,然后设当前枚举到的两个端点为 $[l,r]$.  

    先处理 $[l,r)$,会遇到 $sum_{i=1}^{n} inom{len}{i} inom{k}{i}$ 这个式子.  

    这个式子可以直接 $O(1)$ 组合数算,但是我比较懒用 $O(n^2)$ 递推算的(反正不影响总复杂度)      

    处理完 $[l,r)$ 后再处理 $[r,r]$ 以保证所有边界情况都被考虑好.   

    code: 

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 704  
    #define ll long long 
    #define mod 1000000007
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std; 
    int n;  
    int inv[N],iv[N],fac[N],g[N],A[N];       
    int a[N],b[N],e[N<<1],dp[N][2];  
    void init() {
        inv[1]=1,fac[0]=1;  
        for(int i=1;i<N;++i) fac[i]=(ll)fac[i-1]*i%mod;  
        for(int i=2;i<N;++i) iv[i]=inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod;    
        iv[0]=iv[1]=1;  
        inv[0]=1;  
        for(int i=1;i<N;++i) inv[i]=(ll)inv[i-1]*inv[i]%mod;  
    } 
    int C(int x,int y) {
        return (ll)fac[x]*inv[y]%mod*inv[x-y]%mod; 
    }
    int ADD(int x,int y) {
        return (x+y)>=mod?x+y-mod:x+y;    
    }
    int main() {
        // setIO("input");
        init(); 
        int x,y,z,tot=0;    
        scanf("%d",&n);   
        for(int i=1;i<=n;++i) {
            scanf("%d%d",&a[i],&b[i]);    
            e[++tot]=a[i],e[++tot]=b[i]+1;  
        }    
        sort(e+1,e+1+tot);       
        dp[0][0]=1;   
        for(int i=1;i<=tot;++i) {
            if(e[i]!=e[i-1]) {
                int len=e[i]-e[i-1]-1;          
                if(len) {
                    A[0]=1;                        
                    for(int j=1;j<=min(n,len);++j) {
                        A[j]=(ll)A[j-1]*iv[j]%mod*(len-j+1)%mod;   
                    }     
                    for(int j=1;j<=n;++j) 
                    {
                        g[j]=0;  
                        for(int t=1;t<=min(len,j);++t)             
                            g[j]=ADD(g[j],(ll)A[t]*C(j-1,t-1)%mod);                          
                    }   
                    for(int j=1;j<=n;++j) {                      
                        dp[j][1]=0;   
                        if(a[j]<=e[i-1]&&b[j]>=e[i-1])   {
                            int cnt=0;         
                            for(int k=j;k>=1;--k) {   
                                if(a[k]<=e[i-1]&&b[k]>=e[i-1]) {
                                    ++cnt;                  
                                }
                                if(cnt) dp[j][1]=ADD(dp[j][1],(ll)g[cnt]*dp[k-1][0]%mod); 
                            }
                        }
                    }    
                    for(int j=1;j<=n;++j) {
                        dp[j][0]=ADD(dp[j][0],dp[j][1]);   
                        dp[j][1]=0;  
                    }
                }            
                for(int j=1;j<=n;++j) {        
                    if(a[j]<=e[i]&&b[j]>=e[i]) {
                        for(int k=0;k<j;++k) dp[j][1]=ADD(dp[j][1],dp[k][0]);              
                    }
                }
                for(int j=1;j<=n;++j) {
                    dp[j][0]=ADD(dp[j][0],dp[j][1]); 
                    dp[j][1]=0;  
                }
            }
        }
        int ans=0;
        for(int i=1;i<=n;++i) {
            ans=ADD(ans,dp[i][0]);  
        }
        printf("%d
    ",ans);  
        return 0; 
    }
    

      

  • 相关阅读:
    springboot中filter的配置和顺序执行
    springboot整合fastdfs实现上传和下载
    移动端通过fiddler代理调试PC端代码
    react-native windows 环境搭建
    带你逐行阅读redux源码
    前端单页面拆分多个单页面
    Koa2学习(九)与mongoDB交互
    Koa2学习(八)使用session
    Koa2学习(七)使用cookie
    Koa2学习(六)使用koa-router
  • 原文地址:https://www.cnblogs.com/guangheli/p/13429937.html
Copyright © 2011-2022 走看看