SRM532 D2 L3

本文介绍了一种使用动态规划解决特定棋盘染色问题的方法。该问题要求染色后的棋盘中,每个染色块的四邻域内染色块数为偶数。采用dp[i][j][k]表示前i行的状态,通过二进制处理奇偶性,最终复杂度为O(N*4^M)。文章详细讲解了状态转移方程及滚动数组优化。

Problem Statement

题目大意是给定一个N*M的棋盘,然后棋盘上染色,要求染色满足这样的条件,染色块的四领域内的染色块数为偶数。

用dp[i][j][k]表示1..i行,第i行放置状态为j,奇偶性为k的方案数,用f[i][j][k]表示放置状态为j,奇偶性对应为k的方案数,其中判断奇偶性时用到二进制处理,最后的复杂度为O(N*4^M),

内存方面要用滚动数组优化,解题报告的做法是用三进制,本来没用到f[i][j][k],实现了一个O(N*8^M)的算法,就是在状态转移的时候又枚举了一下,这样在TC上会超时,

用了一个中间数组f存储了中间结果,并优化下存储就可以了~

using namespace std;
#include <iostream>
using namespace std;

const int M = 1000000007;

typedef long long int64;

int64 dp[2][1 << 8][1 << 8], f[2][1 << 8][1 << 8];

class DengklekPaintingSquares
{
public:
int numSolutions(int m, int n)
{
memset(dp, 0, sizeof(dp));
memset(f, 0, sizeof(f));
dp[0][0][0] = 1;
f[0][0][0] = 1;

for(int i = 1; i <= m + 1; i++)
{
memset(dp[i & 1], 0, sizeof(dp[i & 1]));
memset(f[i & 1], 0, sizeof(f[i & 1]));
for(int j = 0; j < (1 << n); j++)
{
for(int k = 0; k < (1 << n); k++)
{
int dj = (j >> 1) ^ ((j << 1) & ((1 << n) - 1)) ^ k;
dp[i & 1][j][k] += f[(i + 1) & 1][dj][dj & j];
dp[i & 1][j][k] %= M;

f[i & 1][j][j & k] += dp[i & 1][j][k];
f[i & 1][j][j & k] %= M;
}
}
}

return f[(m + 1) & 1][0][0];
}
};



转载于:https://www.cnblogs.com/litstrong/archive/2012/02/23/2364940.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值