zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    4. Android框架和工具之 android-async-http
    3. Android框架和工具之 xUtils(BitmapUtils)
    自定义多列排序:C++/Java实现
    Java套接字
    Java泛型
    线程同步之生产者消费者
    面向对象之深复制与浅复制
    谈谈多线程
    递归与尾递归
    单例模式:Instance
  • 原文地址:https://www.cnblogs.com/lawyer/p/7018742.html
Copyright © 2011-2022 走看看