light OJ 1205 数位DP

来源:互联网 发布:图片透视软件 编辑:程序博客网 时间:2024/04/30 22:32

题意:找区间[L,R]内回文数的个数 (没有前导零)

数位dp, 自己设计一下dfs,注意零要特殊考虑, 然后枚举数的长度再dfs即可。

#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>using namespace std;#define LL long longLL l, r;int a[66];LL dp[66][66];LL dfs(int len, int l, int r, bool lim, bool ok) {//ok表示r之后的那位是否有借位,有 ok = 0 否则ok = 1    if(l < r) return !lim || (lim && ok);    if(!lim && ~dp[len][l]) return dp[len][l];    LL ret = 0;    int m = lim ? a[l] : 9;    int i;    for(i = 0; i <= m; i++) {        if(l == len-1 && !i) continue;  //首位为零就跳过        int g = ok;        if(g) g = a[r] >= i;        else g = a[r] > i;        ret += dfs(len, l-1, r+1, lim&&i==m, g);    }    if(!lim) dp[len][l] = ret;    return ret;}LL gao(LL n) {    if(n < 0) return 0;    if(n == 0) return 1;    int len = 0;    while(n) { a[len++] = n%10; n /= 10; }    LL ret = 1;  //要把0加进去    int i;    for(i = len; i >= 1; i--)        ret += dfs(i, i-1, 0, i==len, 1);    return ret;}int main() {    int i, cas;    cin >> cas;    memset(dp, -1, sizeof(dp));    for(int ca = 1; ca <= cas; ca++) {        cin >> l >> r;        if(l > r) swap(l, r);        printf("Case %d: %lld\n", ca, gao(r) - gao(l-1));    }    return 0;}


原创粉丝点击