UVALive

UVALive - 5857

思路:

状压dp,用map写

代码:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define y1 y11
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pli pair<LL, int>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdd pair<double, double>
#define mem(a, b) memset(a, b, sizeof(a))
#define debug(x) cerr << #x << " = " << x << "
";

const int N = 20;
char s[N][N];
pii a[N];
int n, m, cnt, num[N];
LL p[N];
map<LL, int> dp[2];
int main() {
    p[0] = 1;
    for (int i = 1; i < N; ++i) p[i] = p[i-1]*10;
    while(~scanf("%d %d", &n, &m)) {
        if(!n && !m) break;
        for (int i = 0; i < n; ++i) scanf("%s", s[i]);
        cnt = 0;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                if(isdigit(s[i][j])) {
                    a[cnt].fi = i;
                    a[cnt].se = j;
                    num[cnt] = s[i][j]-'0';
                    ++cnt;
                }
            }
        }
        dp[0].clear(); dp[1].clear();
        int now = 0;
        dp[now][0] = 0;
        int k;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                now ^= 1;
                dp[now].clear();
                for (auto t : dp[now^1]) {
                    LL x = t.fi;
                    for (k = 0; k < cnt; ++k) {
                        if((x/p[k])%10 != num[k] && (i*m+j)-(a[k].fi*m+a[k].se) >= m+2) break;
                    }
                    if(k < cnt) continue;
                    if(dp[now].find(x) == dp[now].end()) dp[now][x] = t.se;
                    else dp[now][x] = min(dp[now][x], t.se);
                    if(s[i][j] == '.') continue;
                    for (k = 0; k < cnt; ++k) {
                        if(i-1 <= a[k].fi && a[k].fi <= i+1 && j-1 <= a[k].se && a[k].se <= j+1) {
                            if((x/p[k])%10 == num[k]) break;
                            x += p[k];
                        }
                    }
                    if(k < cnt) continue;
                    if(dp[now].find(x) == dp[now].end()) dp[now][x] = t.se + 1;
                    else dp[now][x] = min(dp[now][x], t.se + 1);
                }
            }
        }
        LL x = 0;
        for (int i = 0; i < cnt; ++i) x += num[i]*p[i];
        printf("%d
", dp[now][x]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/widsom/p/10637220.html