uva 11270 插头dp入门

4 篇文章 0 订阅
1 篇文章 0 订阅

白书的插头dp入门级题目,看了很久差不多懂了但是感觉自己写起来还是挺有难度的

题意:求用1∗2木块将给出的n∗m大小的矩阵填满的方法总数


用dp[i][j]表示第i块位置,并且该位置对应的行数的状态为j的时候的总情况数。

对于每个阶段的每个状态有3种转移方式
(1)不放
(2)竖放
(3)横放

注意第一喂要用滚动数组优化内存

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define rep(i, j, k) for(int i = j; i <= k; i++)

using namespace std;

long long n, m, f[2][1 << 11];
int cur;

void update (int a, int b)
{
	if (b & (1 << m))
		f[cur][b ^ (1 << m)] += f[cur ^ 1][a];    // ?
}

int main ()
{
	while (cin >> n >> m)
	{
		if (m > n)
			swap (n, m);
		cur = 0;
		memset (f, 0, sizeof (f));
		f[0][ ( 1 << m) - 1] = 1;
		rep (i, 1, n)
			rep (j, 1, m)
			{
				cur ^= 1;
				memset (f[cur], 0, sizeof (f[cur]));
				rep (k, 0, (1 << m) - 1)
				{
					update (k, k << 1);
					if (i > 1 && !(k & (1 << m - 1)))
						update (k, (k << 1) ^ (1 << m) ^ 1);
					if (j > 1 && !(k & 1))
						update (k, (k << 1) ^ 3);
				}
			}
		cout << f[cur][ (1 << m) - 1] << endl;
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值