• HDU 3652 区间有13并且这样整除13 的数量(数位DP)


    题目:求1~n的范围里含有13且能被13整除的数字的个数。

    分析:

    dfs(len, num, mod, flag)
    mod记录数字对13取余后的值
    len表示当前位数
    num==0 不含13且上一位不为1
    pre==1 不含13且上一位为1
    pre==2 含13
    flag表示是否可以任意取值(判断范围)。
    如此,记忆化搜索即可得解。

    总结:我是在最后才判断是否可以%13 , 但是这是不可以的 , 经过这道题后,理解更好了 ;

    这里有个式子特别重要 : 关于连加取mod ,      例如: 123%13=(100+20+3)%13 = ((1%13*10+2)%13*10+3)%13; !!!!!  这在数位dp很重要

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    #include <vector>
    
    using namespace std;
    
    #define LL long long
    #define MOD 13
    LL dp[20][3][13];
    int dis[20];
    
    LL dfs(int len, int type, int mod, bool flag)
    {
        if(len < 0)
            return type == 2 && mod == 0;
        if(!flag && dp[len][type][mod]!=-1)
            return dp[len][type][mod];
        int end = flag?dis[len]:9;
        int ans = 0;
        for(int i=0; i<=end; i++)
        {
            if(type == 2 || (type == 1 && i == 3))
                ans += dfs(len-1, 2, (mod*10+i)%MOD, flag&&i==end);
            else
                ans += dfs(len-1, i==1?1:0, (mod*10+i)%MOD, flag&&i==end);
        }
        if(!flag)
            dp[len][type][mod] = ans;
        return ans;
    }
    
    LL solve(LL n)
    {
        int len = 0;
        while(n)
        {
            dis[len++] = n%10;
            n /= 10;
        }
        return dfs(len-1, 0, 0, 1);
    }
    
    int main()
    {
        int n;
        memset(dp, -1, sizeof(dp));
        while(cin>>n)
            cout<<solve(n)<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    Angularjs 中文版API v1.3.9 阅读
    jquery之ajax
    requirejs中 shim
    reqiurejs学习
    angularjs与require的集成摘抄
    安装go-admin
    多种GitHub加速方式
    git初始化仓库操作
    git cherry-pick
    gc问题定位
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/9931931.html
Copyright © 2020-2023  润新知