[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.
", ++ cas, dp[n][0][0]);
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/jklongint/p/5058561.html