1. 程式人生 > >HDU-3852 B-number(數位DP)

HDU-3852 B-number(數位DP)

https://vjudge.net/problem/HDU-3652

題意:給你一個數n,求出含13且能被13整除的數.

程式碼有詳細註釋

#include<bits/stdc++.h>
using namespace std;
int dp[20][15][3];
///dp[i][j][k]i表示位數,j表示mod,k==0,最後一位不是1,k==1,表示最後一位是1,k==2,表示含13 
int a[20];
int dfs(int pos,int mod,int have,bool limit)
{
    int mod_x,have_x,up,ans=0;
    if(pos==-1)
        return mod==0 && have==2;///表示含13且對mod13==0;
    if(!limit&&dp[pos][mod][have]!=-1) return dp[pos][mod][have];///記憶化搜尋
    up=limit?a[pos]:9;
    for(int i=0;i<=up;i++)
    {
        mod_x=(mod*10+i)%13;///同餘
        have_x=have;
        if(have==0&&i==1) have_x=1;///如果上一位不是1,但該位是1;
        if(have==1&&i!=1) have_x=0;///如果上一為是1,但該位是0;
        if(have==1&&i==3) have_x=2;///如果上一位是1,該位是3;
   ///其餘的情況不會改變have的值,比如上一位不是1,該位不是1;上一位是1,該位是1...
        ans+=dfs(pos-1,mod_x,have_x,limit&&i==up);
    }
    if(!limit) dp[pos][mod][have]=ans;///記憶化
    return ans;
}
int slove(int n)
{
    int len=0;
    while(n)
    {
        a[len++]=n%10;
        n/=10;
    }
    return dfs(len-1,0,0,true);
}
int main()
{
    int n;
    memset(dp,-1,sizeof(dp));
    while(cin>>n)
        cout<<slove(n)<<endl;
}