poj2411_Mondriaan's Dream_状压DP(插头)
2018-02-27 20:53
411 查看
题目大意用 1 * 2 的骨牌密铺 h * w 的方格
思路用k记录考虑第(i, j)时的复杂状态,k & (1 << (j - 1)) 为1时表示此时已被之前的操作所覆盖(来自 (i - 1, j) 或 (i, j - 1)),为0时未被覆盖三维dp数组,一直超时,降维后AC#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define INF 0x3f3f3f3f
#define rep0(i, n) for (int i = 0; i < n; i++)
#define rep1(i, n) for (int i = 1; i <= n; i++)
#define rep_0(i, n) for (int i = n - 1; i >= 0; i--)
#define rep_1(i, n) for (int i = n; i > 0; i--)
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define mem(x, y) memset(x, y, sizeof(x))
#define MAXH 15
using namespace std;
typedef long long LL;
int h, w;
LL dp[MAXH][1 << MAXH];
void DP()
{
dp[0][0] = 1;
for (int i = 1; i <= h; i++)
{
if (i > 1)
for (int k = 0; k < (1 << w); k++)
dp[0][k] = dp[w][k];
for (int j = 1; j <= w; j++)
{
mem(dp[j], 0);
int up = 1 << (j - 1), r = 1 << j;
for (int k = 0; k < (1 << w); k++)
{
/**
当(i, j)已被覆盖时,(i, j + 1)不会被覆盖
当(i, j)被覆盖时,竖放后(i, j + 1)被覆盖
*/
dp[j][k ^ up] += dp[j - 1][k];
if ((k & up) == 0 && (k & r) == 0)
{
//考虑横放
dp[j][k ^ r] += dp[j - 1][k];
}
}
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE
while (scanf("%d %d", &h, &w) != EOF && h && w)
{
mem(dp, 0);
DP();
printf("%lld\n", dp[w][0]);
}
return 0;
}
思路用k记录考虑第(i, j)时的复杂状态,k & (1 << (j - 1)) 为1时表示此时已被之前的操作所覆盖(来自 (i - 1, j) 或 (i, j - 1)),为0时未被覆盖三维dp数组,一直超时,降维后AC#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define INF 0x3f3f3f3f
#define rep0(i, n) for (int i = 0; i < n; i++)
#define rep1(i, n) for (int i = 1; i <= n; i++)
#define rep_0(i, n) for (int i = n - 1; i >= 0; i--)
#define rep_1(i, n) for (int i = n; i > 0; i--)
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define mem(x, y) memset(x, y, sizeof(x))
#define MAXH 15
using namespace std;
typedef long long LL;
int h, w;
LL dp[MAXH][1 << MAXH];
void DP()
{
dp[0][0] = 1;
for (int i = 1; i <= h; i++)
{
if (i > 1)
for (int k = 0; k < (1 << w); k++)
dp[0][k] = dp[w][k];
for (int j = 1; j <= w; j++)
{
mem(dp[j], 0);
int up = 1 << (j - 1), r = 1 << j;
for (int k = 0; k < (1 << w); k++)
{
/**
当(i, j)已被覆盖时,(i, j + 1)不会被覆盖
当(i, j)被覆盖时,竖放后(i, j + 1)被覆盖
*/
dp[j][k ^ up] += dp[j - 1][k];
if ((k & up) == 0 && (k & r) == 0)
{
//考虑横放
dp[j][k ^ r] += dp[j - 1][k];
}
}
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE
while (scanf("%d %d", &h, &w) != EOF && h && w)
{
mem(dp, 0);
DP();
printf("%lld\n", dp[w][0]);
}
return 0;
}
相关文章推荐
- poj2411 Mondriaan's Dream(状压dp)
- [POJ2411] Mondriaan's Dream 状压dp
- poj2411 Mondriaan's Dream(状压dp)
- 【POJ2411】Mondriaan's Dream-状态压缩DP(插头DP?)
- poj2411 Mondriaan's Dream--状压dp
- [Poj2411]Mondriaan's Dream(状压dp)(插头dp)
- poj 2411 Mondriaan's Dream 铺砖块(状压dp)
- POJ 2411 Mondriaan's Dream(插头DP,轮廓线)
- [poj 2411]Mondriaan's Dream (状压dp)
- POJ 2411 Mondriaan's Dream(状压DP)
- POJ 2411 Mondriaan's Dream(状压DP)
- poj 2411 Mondriaan's Dream(状压DP)
- Mondriaan's Dream----状压DP
- POJ2411:Mondriaan's Dream(状压dp)
- POJ 2411 Mondriaan's Dream(状压 dp)
- POJ 2411 Mondriaan's Dream (状压dp)
- [POJ 2411]Mondriaan's Dream:状压DP
- HDU 1400 Mondriaan's Dream(状压DP)
- 【poj2411】Mondriaan's Dream 状态压缩dp
- poj2411 Mondriaan's Dream 插头dp做法