UVA - 10237 Bishops

A bishop is a piece used in thegame of chess which is played on a board of square grids. A bishop can only movediagonally from its current position and two bishops attack each other if oneis on the path of the other. In the following figure, the dark squaresrepresent
the reachable locations for bishop B1 formits current position.  The figure also shows that the bishops
B1and B2 are in attacking positions whereas
B1and B3 are not.
B2 and B3are also in non-attacking positions.

Now, given two numbers nand k, your job is to determine the number of ways one can put
kbishops on an n × nchessboard so that no two of them are in attacking positions.

Input

The input file maycontain multiple test cases. Each test case occupies a single line in the inputfile and contains two integers
n (1 ≤ n ≤ 30) and k (0 ≤ k ≤ n2).

A test case containing two zerosfor n and k terminates the input and youwon’t need to process this particular input.

Output

For each test case in the inputprint a line containing the total number of ways one can put the given numberof bishops on a chessboard of the given size so that no two of them are inattacking positions. You may safely assume that this number will be less
than 1015.

 

Sample Input

8 6

4 4

20 40

30 5

0 0

 

Sample Output

5599888

260

0

3127859642656

题意:两个象互不攻击,当且仅当它们不出于同一斜线,一个n*n的棋盘上放k个互不攻击的象有多少种方法。

思路:把棋盘染色成国际象棋的棋盘,那么只有同一颜色上的才会互相攻击,而且不同颜色的互不影响,那么我们分别算不同颜色的

方法。首先将黑白颜色的格子都取出来,那么我们可以考虑第i行放或者不放,如果不放的话结果不变,如果放的话,只有

(len[i]-j+1)的位置可以选,因为前面有(j-1)个会攻击到,那么状态转移是:

dp[i][j] = dp[i-1][j]+(dp[i-1][j-1]*(len[i]-j+1)){len[i]代表第i行的格子个数}因为len[i]不是递增的,其实我们将一半行后面的也拿到前面,结果是不影响的

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
typedef long long ll;
using namespace std;
const int maxn = 35;

ll dp1[maxn][1005], dp2[maxn][1005];
ll len1[maxn], len2[maxn];
int n, k;

void init() {
	len1[1] = len1[2] = 1;
	len2[1] = len2[2] = 2;
	for (int i = 3; i < maxn-2; i += 2) {
		len1[i+1] = len1[i] = len1[i-1] + 2;
		len2[i+1] = len2[i] = len2[i-1] + 2;
	}
}

int main() {
	init();
	while (scanf("%d%d", &n, &k) != EOF && n+k) {
		memset(dp1, 0, sizeof(dp1));
		memset(dp2, 0, sizeof(dp2));
		for (int i = 0; i <= n; i++)
			dp1[i][0] = dp2[i][0] = 1;

		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= k; j++) {
				dp1[i][j] = (len1[i] - j + 1) * dp1[i-1][j-1] + dp1[i-1][j];
				if (i != n)
					dp2[i][j] = (len2[i] - j + 1) * dp2[i-1][j-1] + dp2[i-1][j];
			}

		ll ans = 0;
		for (int i = 0; i <= k; i++)
			ans += dp1[n][i] * dp2[n-1][k-i];

		printf("%lld\n", ans);
	}
	return 0;
}
时间: 2024-10-06 16:55:04

UVA - 10237 Bishops的相关文章

UVA 10237 - Bishops(递推)

UVA 10237 - Bishops 题目链接 题意:问一个n * n棋盘能放k个主教(攻击斜线)的方案数. 思路:递推,首先考虑一个问题,在一个n?n棋盘上,放k个车的方案数. 那么设dp[i][j]为i行用了j个车的方案数,由于每行只能放一个车,那么考虑i行放不放车,如果放车,那么能放的位置有n?(j?1)个位置,为dp[i?1][j?1]?(n?(j?1)). 如果不放那么情况为dp[i?1][j]. 所以递推式为dp[i][j]=dp[i][j?1]+dp[i?1][j?1]?(n?(

uva 10237 - Bishops(dp)

克里斯·厄姆森 谷歌今天在 Code 大会上发布了新的无人驾驶汽车.该汽车看起来像是有轮子的缆车,它既没有驾驶盘,也没有刹车踏板和加速装置.Re/code 采访了谷歌无人驾驶汽车项目主管克里斯·厄姆森(Chris Urmson),期间谈及该项目革命背后的概念.产品何时上路等问题. 谷歌在过去的 5 年里改装了现成车型去试验无人驾驶技术.除了车顶的旋转激光装置外,它们看上去跟普通车没什么不同.而该公司今天发布的汽车看上去则非常怪异.它们又小又圆,配备各种小型黑色传感器(车顶也有旋转激光装置),用泡

dp题目列表

10271 - Chopsticks 10739 - String to Palindrome 10453 - Make Palindrome 10401 - Injured Queen Problem 825 - Walking on the Safe Side 10617 - Again Palindrome 10201 - Adventures in Moving - Part IV 11258 - String Partition 10564 - Paths through the Ho

组合计数&#183;棋盘统计

相关习题: 1. Uva 10237 Bishops 题意:两个象不攻击,当且仅当它们不处在同一条斜线上.输入整数$n(n \leq 30)$,统计在一个$n \times n$的棋盘上放$k$个互不攻击的象有多少种方法.如$N=8, k = 6$时有$5599888$种.

编程题目分类(剪辑)

1. 编程入门 2. 数据结构 3. 字符串 4. 排序 5. 图遍历 6. 图算法 7. 搜索:剪枝,启发式搜索 8. 动态规划/递推 9. 分治/递归 10. 贪心 11. 模拟 12. 算术与代数 13. 组合问题 14. 数论 15. 网格,几何,计算几何 [编程入门] PC 110101, uva 100, The 3n+1 problem, 难度 1 PC 110102, uva 10189, Minesweeper, 难度 1 PC 110103, uva 10137, The T

HDU 1820 / uva 861 Little Bishops

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1820 题意:给你一个n*n的棋盘,让你放k个象,求方法数 象的攻击路线是斜的,所以我们可以将棋盘旋转45°,这样攻击路线就成了水平,象就变成了车 之后可以发现,如果将棋盘分为黑白格子,黑白棋子之间是无法互相攻击的,那我们就可以将他们分开考虑 把棋盘处理成2个下面的图形 设dp[i][j]表示前i行放了j个车的方法数,c[i]表示第i行可以放置的棋子数量,那么转移方程为: dp[i][j] = dp[i-

UVA 861 Little Bishops

https://vjudge.net/problem/UVA-861 题意: 在n*n棋盘上方k个互不攻击的象,求方案数 若两个象在同意对角线上,则会互相攻击 将棋盘黑白染色,则黑格不会攻击白格,白格不会攻击黑格 所以黑白格分开考虑 最终答案= Σ 黑格放i个*白格放k-i个 将所有黑格抽离出来,旋转45° 这样对角线方向就变成了水平方向和竖直方向 问题转化成了 每一行每一列至多放1个 在按每行格子数量从小到大排序 这样每行依次为 2个.2个.4个.4个.6个.6个.8个.8个…… 或者每行一次

UVA 562 Dividing coins --01背包的变形

01背包的变形. 先算出硬币面值的总和,然后此题变成求背包容量为V=sum/2时,能装的最多的硬币,然后将剩余的面值和它相减取一个绝对值就是最小的差值. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define N 50007 int c[102],d

UVA 10341 Solve It

Problem F Solve It Input: standard input Output: standard output Time Limit: 1 second Memory Limit: 32 MB Solve the equation: p*e-x + q*sin(x) + r*cos(x) + s*tan(x) + t*x2 + u = 0 where 0 <= x <= 1. Input Input consists of multiple test cases and te