SGU 223.Little Kings

时间限制:0.25s

空间限制:4M

题意:

在 n*n(n≤10)的棋盘上放 k (k<=n*n)个国王(可攻击相邻的 8 个格子),求使它们无法互相攻击的方案数。



Solution:

采用状态压缩,用k位(k<=n)的二进制数1的位置代表棋盘放置的国王的位置.

先用预处理,求出statu[i]仅考虑一行时满足要求的方案,c[i]是statu[i]状态放置的棋子数.

f[i][j][p] 代表第i行放置状态为 p时且已经放置了j个棋子的方案数

状态转移方程:f[i][j][p]=Σf[i-1][j-c[j]][pp],(满足i-1行的pp与p不冲突)

判断p与pp是否冲突 只要满足

(p & pp) == 0 &&  (p << 1 & pp) == 0 && ( pp<< 1 & p) == 0

最后输出ans=Σf[n][k][pi]

参考代码:

#include <iostream>
#include <cstdio>
#define LL long long
using namespace std;
int powT[11];
int statu[1 << 10], c[1 << 10];
LL f[11][111][1 << 10];
int main() {
	int n, k, tol = 0, t;
	scanf ("%d %d", &n, &k);
	for (int i = 0; i <= ( (1 << n) - 1); i++) {
		if ( ( (i & (i >> 1) ) == 0) && ( (i & (i << 1) ) == 0) ) {
			statu[++tol] = i;
			for (t = i; t > 0; t >>= 1)
				if (t & 1) c[i]++;
		}
	}
	for (int i = 1; i <= tol; i++)
		f[1][c[statu[i]]][statu[i]] = 1;
	for (int i = 2; i <= n; i++) {
		for (int j = 0; j <= k; j++)
			for (int pu = 1; pu <= tol; pu++)
				for (int pv = 1; pv <= tol; pv++) {
					int p1 = statu[pu], p2 = statu[pv];
					if (j >= c[p1] && (p1 & p2) == 0 && ( p1 << 1 & p2) == 0 && ( p2 << 1 & p1) == 0)
						f[i][j][p1] += f[i - 1][j - c[p1]][p2];
				}
	}
	LL ans = 0;
	for (int i = 1; i <= tol; i++)
		ans += f[n][k][statu[i]];
	printf ("%lld", ans);
}

  

SGU 223.Little Kings

时间: 2024-08-16 02:01:21

SGU 223.Little Kings的相关文章

SGU 223 little kings BSOJ2772 状压DP

1896 [SCOI2005]互不侵犯King [问题描述]在n*n(1<=n<=10)的棋盘上放k(0<=k<=n*n)个国王(可攻击相邻的8 个格子),求使它们无法互相攻击的方案总数. [输入格式]输入有多组方案,每组数据只有一行为两个整数n和k. [输出格式]每组数据一行为方案总数,若不能够放置则输出0. [问题分析] 由问题很容易联想起经典的“八皇后”问题,似乎就是“皇后”变成了“国王”,而且格子范围似乎也差不多,所求问题也一样.那么这个问题也能用搜索解决吗? 可稍加分析可

SGU 220~229

SB题一堆,以后为了提高效率,SB题,一眼题一律不码. 220 Little Bishops 题意:求n*n的棋盘上放K个象的放法, 象可以对角线相互攻击 sb题. 221 Big Bishops 如上,一字未变,加个高精度即可,尼玛我现在高精度都能写错,还是滚回pj吧.. 222. Little Rooks 题意:n*n放车,问方案数.n最大10. 尼玛,真的滚回pj组了!?老子还是读过书的. 223 Little King 题意:如上,把车改成王. 状压直接上. 224. Little Qu

【SGU 390】Tickets (数位DP)

Tickets Description Conductor is quite a boring profession, as all you have to do is just to sell tickets to the passengers. So no wonder that once upon a time in a faraway galaxy one conductor decided to diversify this occupation. Now this conductor

ACM: SGU 101 Domino- 欧拉回路-并查集

sgu 101 - Domino Time Limit:250MS     Memory Limit:4096KB     64bit IO Format:%I64d & %I64u Description Dominoes – game played with small, rectangular blocks of wood or other material, each identified by a number of dots, or pips, on its face. The bl

SGU 116 Index of super-prime 数论+完全背包+输出方案

题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=116 题意好晦涩 给你一个不超过一万的数 问它最少可以用多少个“超级素数”来表示 使“超级素数”之和等于它 如果无法这样表示 输出0 否则 按非降序形式输出方案 数论部分就模板的问题 没什么说的 完全背包方面也很常规 说说[输出方案] 背包九讲的伪码给的是二维dp[]的方法 实际上稍加改动就可以用在一维数组上 用一个rec[]记录dp[]的当前状态是从哪个状态转移而来(即上一个状态) 通过

SGU 乱搞日志

SGU 100 A+B :太神不会 SGU 101 Domino: 题目大意:有N张骨牌,两张骨牌有两面有0到6的数字,能相连当且仅当前后数字相同,问能否有将N张骨牌连接的方案?思路:裸的欧拉回路,注意自环,连通 1 //sgu101 2 #include<iostream> 3 #include<cstdio> 4 #include <math.h> 5 #include<algorithm> 6 #include<string.h> 7 #i

SGU 275 To xor or not to xor (高斯消元)

题目地址:SGU 275 首先,贪心的思想,每一二进制位上要尽量是1,而能不能是1用高斯消元来解决.当该位有一个可以使之为1的变元时,就说明这位可以为1,而且令该变元控制该位,然后向低位消元. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h>

SGU 221.Big Bishops(DP)

题意: 给一个n*n(n<=50)的棋盘,放上k个主教(斜走),求能放置的种类总数. Solution : 同SGU 220,加个高精度就好了. code #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <algorithm> using namespace std; string f[2][250][250], ans;

SGU 193.Chinese Girls&#39; Amusement

/* 实际上就是求一个k,满足k<=n/2,且gcd(n,k)=1 如果n为奇数,k为[n/2] 如果n为偶数,k=n/2-1-(n/2)%2 */ #include <iostream> using namespace std; string s; void div2() { string t; int l = s.size() - 1, tem = s[0] - '0'; if (tem > 1) t += '0' + tem / 2; tem &= 1; for (i