luogu Eat the Trees

Posted luoyibujue

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu Eat the Trees相关的知识,希望对你有一定的参考价值。

/*
用和模板类似的方法就行

但是实际上弱化版不用考虑匹配情况限制更加宽松, 只需要保存每个位置有无插头即可,
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#include<cmath>
#define ll long long
#define M 13
#define mmp make_pair
using namespace std;
int read() {
    int nm = 0, f = 1;
    char c = getchar();
    for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
    return nm * f;
}
const int hs = 299987;
int mp[M][M], ex, ey, now, last, bit[30], g[2][300010], tot[2], n, m;
ll ans, f[2][300010];

struct Note {
    int nxt, to;
} note[300010];
int head[300010], cnt = 0;

void insert(int x, ll v) {
    int key = x % hs;
    for(int i = head[key]; i; i = note[i].nxt) {
        if(g[now][note[i].to] == x) {
            f[now][note[i].to] += v;
            return;
        }
    }
    tot[now]++;
    g[now][tot[now]] = x;
    f[now][tot[now]] = v;

    note[++cnt].nxt = head[key];
    head[key] = cnt;
    note[cnt].to = tot[now];
}

void Dp() {
    now = 1, last = 0;
    tot[now] = 1;
    f[now][1] = 1;
    g[now][1] = 0;
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= tot[now]; j++) g[now][j] <<= 1;
        for(int j = 1; j <= m; j++) {
            cnt = 0;
            memset(head, 0, sizeof(head));
            swap(now, last);
            tot[now] = 0;
            ll nowans;
            int nowsta, sd, sr;
            for(int k = 1; k <= tot[last]; k++) {
                nowsta = g[last][k], nowans = f[last][k];
                sd = (nowsta >> bit[j]) % 2, sr = (nowsta >> bit[j - 1]) % 2;

                if(!mp[i][j]) {
                    if(!sd && !sr) insert(nowsta, nowans);
                } else if(!sd && !sr) {
                    if(mp[i + 1][j] && mp[i][j + 1]) insert(nowsta + (1 << bit[j - 1]) + (1 << bit[j]), nowans);
                } else if(!sd && sr) {
                    if(mp[i + 1][j]) insert(nowsta, nowans);
                    if(mp[i][j + 1]) insert(nowsta - (1 << bit[j - 1]) + (1 << bit[j]), nowans);
                } else if(sd && !sr) {
                    if(mp[i + 1][j]) insert(nowsta - (1 << bit[j]) + (1 << bit[j - 1]), nowans);
                    if(mp[i][j + 1]) insert(nowsta, nowans);
                } else {
                    insert(nowsta - (1 << bit[j]) - (1 << bit[j - 1]), nowans);
                    if(i == ex && j == ey) ans += nowans;
                }
            }
        }
    }
}

void init() {
    ans = 0;
    ex = 0, ey = 0;
    memset(f, 0, sizeof(f));
    memset(g, 0, sizeof(g));
    memset(mp, 0, sizeof(mp));
}

int main() {
    int T = read();
    for(int i = 1; i <= 25; i++) bit[i] = i;
    while(T--) {
        init();
        n = read(), m = read();
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                int x = read();
                if(x == 1) mp[i][j] = 1, ex = i, ey = j;
            }
        }
        Dp();
        if(ex == 0 && ey == 0) ans++;
        cout << ans << '
';
    }
    return 0;
}
/*
2
2 4
1 1 1 1
1 1 1 1
6 3
1 1 1
1 0 1
1 1 1
1 1 1
1 0 1
1 1 1

1 
3 3
0 0 0
0 0 0
0 0 0
*/


以上是关于luogu Eat the Trees的主要内容,如果未能解决你的问题,请参考以下文章

Eat the Trees(hdu 1693)

HDU 1693 Eat the Trees

they can eat the leaves at the top of the trees

HDU1663 Eat the Trees

HDU1693 Eat the Trees

HDU1693Eat the Trees(插头dp)