[hdu1693 Eat the Trees]插头dp
题意:用若干条回路覆盖01矩阵里面所有的1的方案数
方法:多回路问题,需要将插头的有无加入状态里,然后沿轮廓线转移即可。简单好写。
#include <bits/stdc++.h> using namespace std; #ifndef ONLINE_JUDGE #include "local.h" #endif // ONLINE_JUDGE #define pb(x) push_back(x) #define mp(x, y) make_pair(x, y) #define all(a) (a).begin(), (a).end() #define mset(a, x) memset(a, x, sizeof(a)) #define mcpy(a, b) memcpy(a, b, sizeof(b)) #define up(a, b) for (int a = 0; a < (b); a ++) #define down(a, b) for (int a = b - 1; (a) >= 0; a --) #define rep(i, a, b) for (int i = a; i <= (b); i ++) #define rrep(i, a, b) for (int i = a; i >= (b); i --) #define cas() int T, cas = 0; cin >> T; while (T --) #define printCas(ch) printf("Case #%d:%c", ++ cas, ch) #define watch(ele) cout << ele << endl; #define in(a) scanf("%d", &a) typedef long long ll; typedef pair<int, int> pii; template<typename T>bool umax(T&a, const T&b){return a<b?(a=b,true):false;} template<typename T>bool umin(T&a, const T&b){return b<a?(a=b,true):false;} int n, m, a[12][12]; ll dp[12][12][1 << 12]; int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); #endif // ONLINE_JUDGE cas() { cin >> n >> m; up(i, n) up(j, m) cin >> a[i][j]; mset(dp, 0); dp[0][0][0] = 1; up(i, n) up(j, m) up(k, 1 << m + 1) { if (j == 0 && k & 1 << m) continue; if (!a[i][j] && (k & 1 << m || k & 1 << j)) continue; int x = i + (j == m - 1), y = (j + 1) % m; if (!a[i][j]) { dp[x][y][k] += dp[i][j][k]; continue; } if ((bool)(k & 1 << m) ^ (bool)(k & 1 << j)) { dp[x][y][k] += dp[i][j][k]; dp[x][y][k ^ 1 << m ^ 1 << j] += dp[i][j][k]; } else { dp[x][y][k ^ 1 << m ^ 1 << j] += dp[i][j][k]; } } printf("Case %d: There are %I64d ways to eat the trees.\n", ++ cas, dp[n][0][0]); } return 0; }