MnZn求助,轮廓线DP,样例能过,但0pts
查看原帖
MnZn求助,轮廓线DP,样例能过,但0pts
470960
Yellow_and_Strong楼主2023/1/18 18:21

rt

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <bitset>

using namespace std;

const int MAX = 12;
const int inf = 1e9;

inline int read()
{
    int x = 0; char ch = getchar();
    while (!isdigit(ch)) ch = getchar();
    while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch xor 48), ch = getchar();
    return x;
}

int n, m, a[MAX][MAX], b[MAX][MAX];
inline void input()
{
    n = read(), m = read();
    for (register int i = 1; i <= n; ++ i)
        for (register int j = 1; j <= m; ++ j)
            a[i][j] = read();
    for (register int i = 1; i <= n; ++ i)
        for (register int j = 1; j <= m; ++ j)
            b[i][j] = read();
}

int f[1 << (MAX << 1)];
bool vis[1 << (MAX << 1)];

int mem_dfs (int sta, int who)
{
    if (vis[sta]) return f[sta];
    f[sta] = who ? -inf : inf;
    int x = n + 1, y = 1;
    for (register int i = n + m - 1; i >= 0; -- i)
    {
        if ((sta >> i) & 1) -- x; else ++ y;
        if (i == n + m - 1) continue;
        if ((((sta >> i) & 3) != 1) or (((sta >> i) & 2) == 2)) continue;
        int lst = sta ^ (3 << i);
        if (who) f[sta] = max(f[sta], mem_dfs(lst, who ^ 1) + a[x - 1][y - 1]);
        else f[sta] = min(f[sta], mem_dfs(lst, who ^ 1) - b[x - 1][y - 1]);
    }
    vis[sta] = true;
    return f[sta];
}
inline void DP()
{
    f[((1 << n) - 1) << m] = 0, vis[((1 << n) - 1) << m] = true;
    printf ("%d\n", ((n * m % 2) ? mem_dfs ((1 << n) - 1, 1) : mem_dfs ((1 << n) - 1, 0)));
}

int main()
{
    input();
    DP();
    return 0;
}
2023/1/18 18:21
加载中...