zoukankan      html  css  js  c++  java
  • [51nod 1327] 棋盘游戏

    有一个N行M列的棋盘,即该棋盘被分为N*M格。现在向棋盘中放棋子,每个格子中最多放一个棋子,也可以一个不放。放完棋子后需要满足如下要求:
    1)对于第i行来说,其从左往右的前left[i] 个格子(即最左侧的left[i] 个连续的格子)中恰好一共有1个棋子;
    2)对于第i行来说,其从右往左的前right[i]个格子(即最右侧的right[i]个连续的格子)中恰好一共有1个棋子;
    3)对于每一列来说,这一列上的所有格子内含有的棋子数不得超过1个。
    其中,1)与2)条件中,对所有 i 满足 left[i]+right[i] <= M,即两个区间不会相交。
    问,符合上述条件情况下棋子的不同放法一共有多少种?输出放法的个数 mod  1,000,000,007后的结果。
     
    例如样例中,只有如下图一种方法。
               
    Input
    第一行包含两个整数,N,M,其中1<=N<=50,2<=M<=200.
    之后有N行,每行两个数left[i],right[i],其中,1<=left[i],right[i]<=M,且 left[i]+right[i] <= M。
    Output
    一个整数,即符合条件的方案数mod 1,000,000,007后的结果。
    Input示例
    2 4
    1 2
    2 1
    Output示例
    1




    打死都想不出系列。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    using namespace std;
    inline int read() {
        int res = 0;char ch=getchar();
        while(!isdigit(ch)) ch=getchar();
        while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48), ch=getchar();
        return res;
    }
    #define reg register
    #define mod 1000000007
    #define ll long long
    #define int long long
    int n, m;
    int L[205], R[205], Mid[205];
    int f[205][205][55];
    int fac[205], C[205][205];
    
    inline int ksm(int x, int y)
    {
        int res = 1;
        while(y)
        {
            if (y & 1) res = (ll)(res * x) % mod;
            x = (ll)(x * x) % mod;
            y >>= 1; 
        }
        return res;
    }
    ll ans;
    signed main()
    {
        n = read(), m = read();
        for (reg int i = 1 ; i <= n ; i ++)
        {
            int l = read(), r = read();
            L[l] ++, R[m+1-r]++;
            for (reg int j = l + 1 ; j <= m - r ; j ++)    Mid[j]++;
        }
        fac[0] = 1;
        for (reg int i = 1 ; i <= 200 ; i ++)
            fac[i] = fac[i-1] * i % mod;
        C[0][0] = 1;
        for (reg int i = 1 ; i <= 200 ; i ++)
        {
            C[i][0] = 1;
            for (reg int j = 1 ; j <= i ; j ++)
                C[i][j] = (C[i-1][j] + C[i-1][j-1]) % mod;
        }
        f[0][0][0] = 1;
        for (reg int i = 0 ; i < m ; i ++)
            for (reg int j = 0 ; j <= i ; j ++)
                for (reg int k = 0 ; k <= n ; k ++)
                {
                    if (j + 1 >= L[i+1]) (f[i+1][j+1-L[i+1]][k+R[i+1]] += (f[i][j][k] * (C[j+1][L[i+1]] * fac[L[i+1]]) % mod) % mod) %= mod; //空着不填或者填左端点
                    if (j >= L[i+1]) {
                        (f[i+1][j-L[i+1]][k+R[i+1]] += (f[i][j][k] * (C[j][L[i+1]] * fac[L[i+1]] * Mid[i+1]) % mod) % mod) %= mod; //放在中间的空行 
                        if (k + R[i+1]) (f[i+1][j-L[i+1]][k+R[i+1]-1] += (f[i][j][k] * (C[j][L[i+1]] * fac[L[i+1]] % mod * (k + R[i+1])) % mod) % mod) %= mod;
                    }
                }
        for (reg int i = 0 ; i <= m ; i ++)
            ans = (ans + f[m][i][0]) % mod;
        printf("%lld
    ", ans);
        return 0;
    }
  • 相关阅读:
    jQuery的平滑页面内锚定链接插件:$.smoothAnchor()
    分享10个超酷的jQuery动画教程
    jQuery技术在线小测试
    分享一个jQuery的小测验(Quiz)插件:jQuizzy
    (SqlServer)不公开存储过程sp_Msforeachtable与sp_Msforeachdb详解
    SQL Server实用操作小技巧集合
    如何加密和解密文件
    winform程序最小化到托盘后没法关机的解决方案
    SQL语句操作大全
    自定义事件
  • 原文地址:https://www.cnblogs.com/BriMon/p/9549411.html
Copyright © 2011-2022 走看看