SPOJ MYQ10 10649. Mirror Number 数位DP

和上次那道CF的差不多,都是要开一个数组来记录已经填了哪些数字,最后再判断符不符合要求。

状态设计也差不多,记录当前位置和长度。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
#include <string>
#include <iostream>
#include <map>
#include <cstdlib>
#include <list>
#include <set>
#include <queue>
#include <stack>

using namespace std;

typedef long long LL;
const int maxn = 50;
char buf1[maxn],buf2[maxn];
int len,lim[maxn],rec[maxn];
LL f[maxn][maxn];

inline bool check(char *buf) {
    for(int i = 0;i <= len / 2;i++) {
        if(buf[i] != buf[len - i - 1]) return false;
        if(buf[i] != '1' && buf[i] != '8' && buf[i] != '0') return false;
    } 
    return true;
}

LL dfs(int now,int str,int bound) {
    if(now == 0) return 1;
    int m = bound ? lim[now - 1] : 9;
    if(str != -1 && !bound && f[now][str] != -1) return f[now][str];
    LL ret = 0;
    for(int i = 0;i <= m;i++) if(i == 1 || i == 8 || i == 0) {
        if(i && str == -1) str = now;
        if(str == -1) ret += dfs(now - 1,-1,bound && i == m);
        else {
            if(now <= str / 2 && rec[str - now] != i) continue;
            rec[now - 1] = i;
            ret += dfs(now - 1,str,bound && i == m);
        }
    }
    if(!bound && str != -1) f[now][str] = ret;
    return ret;
}

inline void solve() {
    memset(rec,0,sizeof(rec));
    LL ret1,ret2;
    len = strlen(buf1);
    for(int i = 0,pos = len - 1;i < len;i++,pos--) lim[pos] = buf1[i] - '0';
    ret1 = dfs(len,-1,1) - check(buf1);

    len = strlen(buf2);
    for(int i = 0,pos = len - 1;i < len;i++,pos--) lim[pos] = buf2[i] - '0';
    ret2 = dfs(len,-1,1);
    cout << ret2 - ret1 << endl;
}

int main() {
    memset(f,-1,sizeof(f));
    int T; scanf("%d",&T);
    LL ret1,ret2;
    memset(f,-1,sizeof(f));
    while(T--) {
        scanf("%s%s",buf1,buf2);
        solve();
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/rolight/p/3894676.html