HDU-3652 B-number 数位dp

题目链接:https://cn.vjudge.net/problem/HDU-3652

题意

问1~n里包含13并可被13整除的数字个数。

思路

数位dp了,注意维护模13的值mod。
注意mod同样是一个状态,其实这题提醒我dp函数的参数里除了limit和lead以外基本都是状态
因为都被拿去传递了,不是状态就不需要这个参数了。

提交过程

AC

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1000+20;
long long data[maxn][13][4];
// state: 0 for none, 1 for pre==1, 2 for include 13
char num[maxn];

long long dp(int pos, int state, bool lim, int mod){
    if (pos==-1) return state==2 && mod==0;
    if (!lim && data[pos][mod][state]>0)
        return data[pos][mod][state];

    long long ans=0;
    int up=lim?(num[pos]-'0'):9;
    for (int i=0; i<=up; i++){
        int next_state;
        if (state==0 && i==1) next_state=1;
        else if (state==0) next_state=0;
        else if (state==1 && i==3) next_state=2;
        else if (state==1 && i==1) next_state=1;
        else if (state==1) next_state=0;
        else if (state==2) next_state=2;

        ans+=dp(pos-1, next_state, lim && i==up, (mod*10+i)%13);
    }
    
    if (!lim) data[pos][mod][state]=ans;
    return ans;
}

long long solve(long long n){
    sprintf(num, "%lld", n);
    int len=strlen(num);
    reverse(num, num+len);
    return dp(len-1, 0, true, 0);
}

int main(void){
    long long n;
    memset(data, -1, sizeof(data));

    while (scanf("%lld", &n)==1 && n)
        printf("%lld\n", solve(n));

    return 0;
}

Time Memory Length Lang Submitted
15ms 1628kB 1199 G++ 2018-08-15 09:50:05

posted on 2018-08-16 19:11  糖栗子  阅读(122)  评论(0编辑  收藏  举报

导航