HDU3652 常规数位dp入门

Problem Description
A wqb-number, or B-number for short, is a non-negative integer whose decimal form contains the sub- string “13” and can be divided by 13. For example, 130 and 2613 are wqb-numbers, but 143 and 2639 are not. Your task is to calculate how many wqb-numbers from 1 to n for a given integer n.

Input
Process till EOF. In each line, there is one positive integer n(1 <= n <= 1000000000).

Output
Print each answer in a single line.

Sample Input
13
100
200
1000

Sample Output
1
1
2
2

智障很久,%13我开了12位…..
没难点,WA就是因为我智障
其中dp[shiji]那一维不用也能过,这个我不明白为什么…..再看看….看懂后补充

#include
#include
#include
using namespace std;
long long n,tu[20],dp[20][10][13][3];
long long kuaisumi(long long shu,long long zhishu)
{
    if(zhishu==0)return 1;
    long long q=1;
    while(zhishu)
    {
        if(zhishu&1)q*=shu;
        shu*=shu;
        zhishu>>=1;
    }
    return q;
}
long long dfs(long long chang,long long zhuangtai,long long biaoji,long long shiji,long long yushu)
{
    if(biaoji!=0&&dp[chang][shiji][yushu][zhuangtai]!=-1)return dp[chang][shiji][yushu][zhuangtai];
    if(chang==0)
    {
        if(zhuangtai==2&&yushu==0)return dp[chang][shiji][yushu][zhuangtai]=1;
        else return dp[chang][shiji][yushu][zhuangtai]=0;
    }
    int jiexian=biaoji?9:tu[chang];
    long long sum=0;
    for(int a=0;a<=jiexian;a++)
    {
        if(zhuangtai==2||(zhuangtai==1&&a==3))
        {
            if(a==jiexian&&jiexian==tu[chang]&&biaoji==0)sum+=dfs(chang-1,2,0,a,(yushu+a*kuaisumi(10,chang-1))%13);
            else sum+=dfs(chang-1,2,1,a,(yushu+a*kuaisumi(10,chang-1))%13);
        }
        else
        {
            if(a==1)
            {
                if(a==jiexian&&jiexian==tu[chang]&&biaoji==0)sum+=dfs(chang-1,1,0,a,(yushu+a*kuaisumi(10,chang-1))%13);
                else sum+=dfs(chang-1,1,1,a,(yushu+a*kuaisumi(10,chang-1))%13);
            }
            else
            {
                if(a==jiexian&&jiexian==tu[chang]&&biaoji==0)sum+=dfs(chang-1,0,0,a,(yushu+a*kuaisumi(10,chang-1))%13);
                else sum+=dfs(chang-1,0,1,a,(yushu+a*kuaisumi(10,chang-1))%13);
            }
        }
    }
    if(biaoji)dp[chang][shiji][yushu][zhuangtai]=sum;
    return sum;
}
int main()
{
    while(cin>>n)
    {
        memset(dp,-1,sizeof(dp));
        long long q=n;
        tu[0]=0;
        while(q)
        {
            tu[++tu[0]]=q%10;
            q/=10;
        }
    //  cout<
        cout<0],0,0,0,0)<return 0;
}

你可能感兴趣的:(ACM练习,动态规划)