• Bishops


    题意:

    给定一个 $n*n$ 的国际棋盘,求问在上面放 $K$ 个象的方案数。

    解法:

    首先可以发现黑格和白格互不干扰,这样我们可以将黑格,白格分别求出。

    考虑 $f(i,j)$ 表示坐标化后考虑长度为 $i,i-2,i-4,...$ 的 $y=x$ 斜线,放了 $j$ 个棋子的方案数。

    这样有

    $$f(i,j) = f(i-2,j) + 2(i-j+1)f(i-2,j-1) + (i-j+2)(i-j+1)f(i-2,j-2) , i<n$$

    $$f(i,j) = f(i-2,j) + (i-j+1)f(i-2,j-1), j = n$$

    $$ans = sum_{i=0}^K{f(n,i) cdot f(n-1,K-i)}$$

    #include <bits/stdc++.h>
    
    #define LL unsigned long long
    
    const int N = 31;
    
    using namespace std;
    
    int n,K;
    LL f[N][N*N];
    
    int main()
    {
        while(scanf("%d%d",&n,&K),n||K)
        {
            if(n==1)
            {
                cout<<1<<endl;
                continue;
            }
            memset(f,0,sizeof(f));
            f[0][0] = 1;
            f[1][0] = 1;
            f[1][1] = 2;
            for(int i=2;i<=n;i++)
            for(int j=0;j<=i;j++)
            {
                f[i][j] = f[i-2][j];
                if(j>=1)
                {
                    if(i<n)
                    {
                        f[i][j] += f[i-2][j-1] * 2LL * (i-j+1LL);
                        f[i][j] += f[i-2][j-2] * (i-j+2LL)*(i-j+1LL);
                    }
                    else f[i][j] += f[i-2][j-1] * (i-j+1LL);
                }
            }
            LL ans = 0;
            for(int i=0;i<=K;i++)
                ans += f[n][i] * f[n-1][K-i];
            cout << ans << endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    C#、.NET Framework、CLR的关系
    C# out和ref区别
    声明式事务管理
    SSH项目搭建后的简化
    SSH项目的搭建
    SSH的框架整合
    Swift
    如何下载String jar包
    SSH(struts2,spring4,hibernate5)详解
    SSH框架的简化(struts2、spring4、hibernate5)
  • 原文地址:https://www.cnblogs.com/lawyer/p/7018742.html
Copyright © 2020-2023  润新知