您的位置:首页 > 其它

hdu1693 Eat the Trees (插头dp)

2014-12-26 12:15 309 查看
题意:n*m的矩阵,1表示可走,0表示障碍,找出一条或多条回路每个可走的点恰好走一次,问方法数。

思路:

因为允许多条回路,所以不需要考虑插头是左括号还是右括号,可以用2进制表示插头。

用滚动数组实现,为了节约空间。

还有航电上一定要用%I64d,害得我%lld交WA了无数次。

代码(0MS, 1472K):

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>

using namespace std;

int T;
int n, m;
int map[12][12];
long long dp[12][1 << 12];
int main() {
scanf("%d", &T);
int cas = 1;
while (T--) {
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
scanf("%d", &map[i][j]);
memset(dp, 0, sizeof(dp));
dp[m][0] = 1;
for (int i = 1; i <= n; i++) {
for (int k = 0; k < (1 << m); k++)
dp[0][k << 1] = dp[m][k];
for (int j = 1; j <= m; j++) {
for (int k = 0; k < (1 << m + 1); k++) {
int x = 1 << j - 1;
int y = 1 << j;
bool p = x & k;
bool q = y & k;
if (!map[i][j]) {
if (!p && !q) dp[j][k] = dp[j - 1][k];
else dp[j][k] = 0;
} else {
if (p == q) dp[j][k] = dp[j - 1][k ^ x ^ y];
else dp[j][k] = dp[j - 1][k] + dp[j - 1][k ^ x ^ y];
}
}
}
}
printf("Case %d: There are %I64d ways to eat the trees.\n", cas++, dp[m][0]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: