zoukankan      html  css  js  c++  java
  • [机房测试] 下棋

    Description

    (n) 个白色棋子,(m) 个黑色棋子,现在需要把他们排成一排,要求对于任意一段棋子,其中的白色棋子和黑色棋子的差不能超过 (k)

    (nleq 150,kleq 20)

    Solution

    考虑增量构造,假设前 (i-1) 个棋子全满足限制,再增加一个棋子还需要满足什么条件?只需要保证新出来的 (i) 个区间中差值最大的也小于等于 (K),所以只需要记录后缀差值的最大值即可转移。记 (dp_{i,j,k,l}) 表示用了 (i) 个白子 (j) 个黑子,白减黑的最大值为 (k),黑减白的最大值为 (l) 的方案数。转移比较显然。复杂度 (O(n^2k^2))

    #include<stdio.h>
    
    const int N=153;
    const int M=21;
    const int Mod=1e9+7;
    
    int n,m,K;
    int dp[N][N][M][M];
    
    inline void add(int &x,int y){x+=y; if(x>=Mod) x-=Mod;}
    inline int max(int x,int y){return x>y? x:y;}
    inline int min(int x,int y){return x<y? x:y;}
    
    int main(){
        freopen("chess.in","r",stdin);
        freopen("chess.out","w",stdout);
        scanf("%d%d%d",&n,&m,&K);
        dp[0][0][0][0]=1;
        for(int i=0;i<=n;i++)
        for(int j=0;j<=m;j++)
        for(int l=0,rgl=min(K,i);l<=rgl;l++)
        for(int r=0,rgr=min(K,j);r<=rgr;r++){
            if(i!=n&&l!=K) add(dp[i+1][j][l+1][max(0,r-1)],dp[i][j][l][r]);
            if(j!=m&&r!=K) add(dp[i][j+1][max(0,l-1)][r+1],dp[i][j][l][r]);
        }
        int ans=0;
        for(int l=0,rgl=min(K,n);l<=rgl;l++)
            for(int r=0,rgr=min(K,m);r<=rgr;r++) add(ans,dp[n][m][l][r]);
        printf("%d",ans);
    }
    
    // 150 150 19
    
  • 相关阅读:
    BZOJ2243: [SDOI2011]染色
    BZOJ1036: [ZJOI2008]树的统计Count
    转自 x_x_的百度空间 搞ACM的你伤不起
    wcf test client
    wcf test client
    log4net编译后命名空间找不到的问题
    log4net编译后命名空间找不到的问题
    Hive Getting Started
    Hive Getting Started
    刚听完CSDN总裁蒋涛先生的学术报告
  • 原文地址:https://www.cnblogs.com/wwlwQWQ/p/15501012.html
Copyright © 2011-2022 走看看