ZOJ 2563 Long Dominoes(状压DP)
2014-12-13 21:09
323 查看
给定一个m*n的方格子,要求用3*1的骨牌去覆盖,骨牌可以用横放或者竖放,问最终有多少种放置方式,将其铺满。
分析:由于最多30行,每行最多9列,所以可以按行来dp,设计每行的状态从而进行转移,考虑每个骨牌放置对下一行的影响,共有0,1,2,3种方式,0对应横放或者竖放时最下面那
个格子,此行对下一行没有影响,1,竖放时第1个,2竖放时第2个,这样进行转移。注意,第i行横放时要求上一行相应位置状态为0。
思路及代码都来自这里,其实不会做这题,看了才了解。
代码:
View Code
分析:由于最多30行,每行最多9列,所以可以按行来dp,设计每行的状态从而进行转移,考虑每个骨牌放置对下一行的影响,共有0,1,2,3种方式,0对应横放或者竖放时最下面那
个格子,此行对下一行没有影响,1,竖放时第1个,2竖放时第2个,这样进行转移。注意,第i行横放时要求上一行相应位置状态为0。
思路及代码都来自这里,其实不会做这题,看了才了解。
代码:
#include <cstdio> #include <iostream> #include <cstdlib> #include <cstring> #include <cmath> #include <map> #include <vector> #define pb push_back #define mp make_pair #define esp 1e-14 #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 #define sz(x) ((int)((x).size())) #define pf(x) ((x)*(x)) #define pb push_back #define in freopen("solve_in.txt", "r", stdin); #define bug(x) printf("Line : %u >>>>>>\n", (x)); #define inf 0x0f0f0f0f using namespace std; typedef long long LL; typedef map<LL, int> MPS; typedef pair<LL, LL> PII; const int M = (int)1e9 + 7; const int maxn = 110; const int maxm = 1111; LL dp[maxn][23][maxm]; int n, m, c, d; char maze[maxn][11]; int dig[11]; void getDig(int x) { memset(dig, 0, sizeof dig); int len = 0; while(x) { dig[len++] = x&1; x >>= 1; } } bool check(char *s, int x) { for(int i = 0; s[i]; i++) { if((x&1) && s[i] == '0') return false; x >>= 1; } return true; } void dfs(int pre, int num, int st, int cur, int state, int cnt) { if(cnt > d) return; if(cur == m) { dp[pre+1][cnt][state] = (dp[pre+1][cnt][state]+dp[pre][num][st])%M; return; } if(maze[pre+1][cur] == '0') { dfs(pre, num, st, cur+1, state, cnt); } else if(dig[cur] == 0) { if(cur+1 < m && dig[cur+1] == 0 && maze[pre+1][cur+1] == '1') dfs(pre, num, st, cur+2, state, cnt); if(pre+1 < n && maze[pre+2][cur] == '1') dfs(pre, num, st, cur+1, state+(1<<cur), cnt); dfs(pre, num, st, cur+1, state, cnt+1); } else { dfs(pre, num, st, cur+1, state, cnt); } } int main() { while(scanf("%d%d%d%d", &n, &m, &c, &d) == 4) { memset(dp, 0, sizeof dp); for(int i = 1; i <= n; i++) scanf("%s", maze[i]); dp[0][0][0] = 1; for(int i = 0; i < n; i++) { int j; if(i == 0) { j = 0; getDig(j); int x = 0; if(dp[i][x][j]) dfs(i, x, j, 0, 0, x); } else { for(int j = 0; j < (1<<m); j++) { if(check(maze[i], j) == false) continue; getDig(j); for(int x = 0; x <= d; x++) if(dp[i][x][j]) dfs(i, x, j, 0, 0, x); } } } LL ans = 0; for(int i = c; i <= d; i++) ans = (ans + dp [i][0])%M; printf("%lld\n", ans); } return 0; }
View Code
相关文章推荐
- zoj2563 Long Dominoes(状压dp)
- ZOJ 2563 Long Dominoes(状态压缩+dp)
- ZOJ 2563 Long Dominoes(状态压缩DP)
- ZOJ Problem Set - 2563 Long Dominoes 【如压力dp】
- zoj 2563 Long Dominoes (状态压缩dp)
- ZOJ 2994 && HDU 1992 Tiling a Grid With Dominoes (状压DP)
- zoj 2563 Long Dominoes
- Long Dominoes(ZOJ 2563状压dp)
- ZOJ Problem Set - 2563 Long Dominoes 【状压dp】
- J - Long Dominoes (状态dp)
- zoj 3812 We Need Medicine (dp 状压)
- ZOJ 3471 Most Powerful(状压DP)
- ZOJ 3777 Problem Arrangement(状压DP)
- ZOJ 2673 Hexagon and Rhombic Dominoes (状态压缩+dp)
- Long Dominoes (状态dp)
- HDU 1992 Tiling a Grid With Dominoes (状压 dp)
- HDU 1992 Tiling a Grid With Dominoes (状压dp)
- ZOJ 3777 Problem Arrangement (状压DP)
- ZOJ-3777-Problem Arrangement(状压DP)
- ZOJ 3777 - Problem Arrangement(状压DP)