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
    
  • 相关阅读:
    超简单实例使用websocket进行server和client实时通信
    antd的table行key自增长
    selenium元素定位Xpath,Contains,CssSelector
    slenium使用鼠标+键盘事件或者双击实现代码
    使用python+pychram进行API测试(接口测试)初级STEP 1
    linux命令小常识
    sql中limit使用方法
    Swagger-API测试工具实战
    写 test-case心得
    测试之路之[前奏]
  • 原文地址:https://www.cnblogs.com/wwlwQWQ/p/15501012.html
Copyright © 2011-2022 走看看