UVA - 10401 Injured Queen Problem

题目大意:给出一个字符串,要求在n * n(n为字符串的长度)的棋盘上摆放n个受伤的皇后,受伤的皇后只能攻击到同一列和它周围8个格子,如果字符串中第i个字符为'?'表示第i + 1个皇后可以摆放在任意行,如果为1 ~ F表示第i+1个皇后必须摆放在第str[i]行, 问,有多少种不同的摆法?


解题思路:一开始用递归 + 记忆化, 结果超时了, 后来发现其实可以写成递推,dp[i][j]代表第i个皇后摆放在第j行的摆法种类, dp[i][j] = dp[i - 1][k] ( 0 < k < n && abs (j - k) > 1)。

#include <cstdio>
#include <cstring>

int trans(char x) {
	if (x >= 'A')
		return x - 'A' + 9;
	return x - '0' - 1; 
}

int main() {
	char s[20];
	while (scanf("%s", s) != EOF) {
		long long DP[20][20] = {0};
		int n = strlen(s);
		if (s[0] == '?')
			for (int i = 0; i < n; i++)
				DP[0][i] = 1;
		else
			DP[0][trans(s[0])] = 1;

		for (int i = 1; i < n; i++)
			if (s[i] == '?') {
				for (int j = 0; j < n; j++)
					for (int k = 0; k < n; k++)
						if (k - j > 1 || j - k > 1)
							DP[i][j] += DP[i-1][k];
			} else 
				for (int k = 0; k < n; k++)
					if (k - trans(s[i]) > 1 || trans(s[i]) - k > 1)
						DP[i][trans(s[i])] += DP[i-1][k];

		long long ans = 0;
		for (int i = 0; i < n; i++)
			ans += DP[n-1][i];
		printf("%lld\n", ans);
	}
	return 0;
}


你可能感兴趣的:(UVA - 10401 Injured Queen Problem)