您的位置:首页 > 运维架构

uva 10237 - Bishops(dp)

2014-05-29 09:46 232 查看
题目链接:uva 10237 - Bishops

题目大意:给出n和k,问在n∗n的棋盘上放k个主教互相不攻击能有多少种方法,主教的攻击方式是斜线。

解题思路:将棋盘旋转45度,然后将黑白格子互相分开,因为在国际里面,黑格的主教是永远无法攻击到白格的主教。所以将黑白格分开考虑。

然后对于一种格子的颜色来说,它就类似与在一个棋盘上放车,dp[i][j]表示i行放了j个车,dp[i][j]=dp[i−1][j]+(n−j+1)∗dp[i−1][j],这题的n是可变的,并且还是先增加后减少,但是没事,可以将行数按照长短顺序处理,是不影响结果的。

最后用加法原理,枚举黑格上主教的数量,相加即可。
#include <cstdio>
#include <cstring>

typedef long long ll;
const int N = 40;

int n, k;
ll b
[N*N], w
[N*N];

void init () {
memset(b, 0, sizeof(b));
memset(w, 0, sizeof(w));
b[0][0] = w[1][0] = 1;
for (int i = 1; i <= n; i++) {
b[i][0] = b[i-1][0];

int l = (i+1)/2 * 2 - 1;
for (int j = 1; j <= l && j <= k; j++)
b[i][j] = b[i-1][j] + (ll)(l-j+1) * b[i-1][j-1];
}

for (int i = 2; i <= n; i++) {
w[i][0] = w[i-1][0];

int l = i/2 * 2;
for (int j = 1; j <= l && j <= k; j++)
w[i][j] = w[i-1][j] + (ll)(l-j+1) * w[i-1][j-1];
}
}

int main () {
while (scanf("%d%d", &n, &k) == 2 && n + k) {
init();

ll ans = 0;
for (int i = 0; i <= k; i++)
ans = ans + b
[i] * w
[k-i];
printf("%lld\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: