hdu-3652 B-number 数位DP

http://acm.hdu.edu.cn/showproblem.php?pid=3652

求解所有含有13且被13整除的数。

思路:除了数位DP基本的两维,还需要维护数字头部情况,此外遇到整除问题,我们还需要维护余数。

#include <iostream>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <cstdio>
#include <algorithm>
#define LL long long
using namespace std;
const LL N = 1000000010;
const LL INF = 100000009;
LL dp[10][10][13][2];//bit,num,mod,type(0:no 13,1:13)
LL bit[10];
void init()
{
    bit[0] = 1;
    for (LL i = 1; i < 10; i++)bit[i] = bit[i - 1] * 10,bit[i]%=13;
    memset(dp, 0, sizeof dp);
    LL  temp = 0;
    for (LL i = 0; i < 10; i++)
        dp[0][i][i][0] = 1;
    for (LL len = 1; len < 10; len++)
    {
        temp = 0;
        for (LL i = 0; i < 10; i++)
        {
            for (LL m = 0; m < 13; m++)
            {
                for (LL pi = 0; pi < 10; pi++)
                {
                    LL temp=bit[len] * i;
                    LL km = (temp + m) % 13;
                    if (i == 1&&pi==3)
                    {
                        dp[len][i][km][1] += dp[len - 1][pi][m][0];
                        dp[len][i][km][1] += dp[len - 1][pi][m][1];
                    }
                    else
                    {
                        dp[len][i][km][0] += dp[len - 1][pi][m][0];
                        dp[len][i][km][1] += dp[len - 1][pi][m][1];
                    }
                }
                
            }
        }
    }
}
LL arr[100];
LL dfs(LL pos, LL pre,LL mod,LL add)
{
    //if (pos == -1)return add*(mod==0);
    if (pos == -1)return 0;
    LL num = arr[pos];
    LL cnt = 0;
    for (LL i = 0; i < num; i++)
    {
        cnt += dp[pos][i][(13-mod)%13][1];
        if (add||(pre==1&&i==3))
            cnt += dp[pos][i][(13 - mod) % 13][0];
    }
    if (pre == 1 && num == 3) add = 1;
    
    return cnt + dfs(pos - 1, num,(mod+bit[pos]*num)%13,add);
}
LL sol(LL x)
{
    if (x == 0) return 0;
    LL siz = 0;
    while (x)
        arr[siz++] = x % 10, x /= 10;
    LL ans = 0;
    ans = dfs(siz - 1, -1,0,0);
    return ans;
}
int main() {
    cin.sync_with_stdio(false);
    LL n,m;
    init();
    while (cin >> n)
    {
        cout << sol(n+1) << endl;
    }
    return 0;
}

 

posted @ 2017-09-07 16:06  Luke_Ye  阅读(129)  评论(0编辑  收藏  举报