zoukankan      html  css  js  c++  java
  • Hdu 3652 B-number (同余数位DP)

    题目链接:

      Hdu 3652 B-number

    题目描述:

      给出一个数n,问 [1, n]区间内有几个数能被13整除并且还有13这个子串?

    解题思路:

      能整除的数位DP,确定好状态随便搞搞就能过了。dp[x][mod][y][z] 表示 x位的整数,mod 13 等于几, y表示是否出现过13, 最后一位是z。
      还有就是发现记忆化搜索 + 数位dp写出来真的很美讷。不说了,直接上代码,干净粗暴。 

    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const int maxn = 15;
    int dp[maxn][maxn][maxn][maxn], bit[maxn];
    
    int dfs (int pos, int mod, bool s, int num, bool flag)
    {
        if (pos == -1)  //每个位置都满了
            return mod==0 && s; //满足题意返回true
            
        //对于flag==1的时候,还是要向下搜索的,直接返回可能会加多
        if (!flag && dp[pos][mod][s][num] != -1)    
            return dp[pos][mod][s][num];
        
        //如果前面的数都是等于n的,辣么当前这位也不能大于bit[pos]
        int len = flag?bit[pos]:9;
        int ans = 0;
        
        for (int i=0; i<=len; i++)
            ans += dfs (pos-1, (mod*10+i)%13, s||(num==1&&i==3), i, flag&&(i==len));
            
        if (!flag)
            dp[pos][mod][s][num] = ans;
        return ans;
    }
    int solve (int n)
    {
        int pos = 0;
        while (n)
        {
            bit[pos ++] = n % 10;
            n /= 10;
        }
        return dfs (pos-1, 0, 0, 0, 1);
    }
    
    int main ()
    {
        int n;
        memset (dp, -1, sizeof(dp));
    
        while (scanf ("%d", &n) != EOF)
            printf ("%d
    ", solve (n));
        return 0;
    }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    批量创建账号脚本
    shell 批量创建_备份 mysql 数据库 表
    优化chkconfig
    cut 命令
    Shell for 循环
    while 读取文件内容
    生成随机数
    linux 资源管理
    shell 脚本后台运行知识
    while 语句
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4918505.html
Copyright © 2011-2022 走看看