HDU1693 Eat the Trees(zerojudge a228)
传送门:
https://zerojudge.tw/ShowProblem?problemid=a228
http://acm.hdu.edu.cn/showproblem.php?pid=1693
【题解】
插头dp第一题(难以置信我高中oi没有写过23333)
方程很简单,自己推一推插头的地方的连通性即可
放几张图跑了
# include <stdio.h> # include <string.h> # include <iostream> # include <algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef long double ld; const int M = 11 + 10, MAX_STATUS = (1 << 12) + 3; const int mod = 1e9 + 7; int n, m, a[M][M], tCase = 0; ll f[M][M][MAX_STATUS]; inline void sol() { cin >> n >> m; for (int i=1; i<=n; ++i) for (int j=1; j<=m; ++j) scanf("%d", &a[i][j]); int STATUS_SIZE = (1 << m+1) - 1; int STATUS_SIZE_T = (1 << m) - 1; f[0][m][0] = 1; for (int i=1; i<=n; ++i) { for (int sta=0; sta<=STATUS_SIZE_T; ++sta) f[i][0][sta << 1] = f[i-1][m][sta]; for (int j=1; j<=m; ++j) for (int sta=0; sta<=STATUS_SIZE; ++sta) { bool cur1 = (sta & (1 << j-1)), cur2 = (sta & (1 << j)); if(a[i][j] == 1) { if(cur1 && cur2) f[i][j][sta] = f[i][j-1][sta - (1 << j-1) - (1 << j)]; else if(cur1 ^ cur2) { int STA = (sta | (1 << j-1) | (1 << j)); f[i][j][sta] = f[i][j-1][STA - (1 << j-1)] + f[i][j-1][STA - (1 << j)]; } else f[i][j][sta] = f[i][j-1][sta | (1 << j-1) | (1 << j)]; } else { if(!cur1 && !cur2) f[i][j][sta] = f[i][j-1][sta]; else f[i][j][sta] = 0; } } } cout << "Case " << ++tCase << ": There are " << f[n][m][0] << " ways to eat the trees.\n"; } int main() { int T; cin >> T; while(T--) sol(); return 0; }
# include <stdio.h> # include <string.h> # include <iostream> # include <algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef long double ld; const int M = 11 + 10, MAX_STATUS = (1 << 12) + 3; const int mod = 1e9 + 7; int n, m, a[M][M], tCase = 0; int f[M][M][MAX_STATUS]; inline void sol() { cin >> n >> m; for (int i=1; i<=n; ++i) for (int j=1; j<=m; ++j) scanf("%d", &a[i][j]); int STATUS_SIZE = (1 << m+1) - 1; int STATUS_SIZE_T = (1 << m) - 1; f[0][m][0] = 1; for (int i=1; i<=n; ++i) { for (int sta=0; sta<=STATUS_SIZE_T; ++sta) f[i][0][sta << 1] = f[i-1][m][sta]; for (int j=1; j<=m; ++j) for (int sta=0; sta<=STATUS_SIZE; ++sta) { bool cur1 = (sta & (1 << j-1)), cur2 = (sta & (1 << j)); if(a[i][j] == 1) { if(cur1 && cur2) f[i][j][sta] = f[i][j-1][sta - (1 << j-1) - (1 << j)]; else if(cur1 ^ cur2) { int STA = (sta | (1 << j-1) | (1 << j)); f[i][j][sta] = f[i][j-1][STA - (1 << j-1)] + f[i][j-1][STA - (1 << j)]; if(f[i][j][sta] >= mod) f[i][j][sta] -= mod; } else f[i][j][sta] = f[i][j-1][sta | (1 << j-1) | (1 << j)]; } else { if(!cur1 && !cur2) f[i][j][sta] = f[i][j-1][sta]; else f[i][j][sta] = 0; } } } cout << "Case " << ++tCase << ": " << f[n][m][0] << endl; } int main() { int T; cin >> T; while(T--) sol(); return 0; }
上面hdu,下面zerojudge