hdu5179(数位dp)

 

传送门:beautiful number

题意:令 A=∑ni=1ai?10n?i(1≤ai≤9)(n为A的位数)。若A为“漂亮的数”当且仅当对于任意1≤i<n满足a[i]≥a[i+1]且对于任意1≤i≤n,i<j≤n,满足a[i] mod a[j]=0(例如931是一个“漂亮的数”而87不是),求在区间[L,R](包含L和R)里“漂亮的数”的个数。

分析:数位dp较为简单,dp[pos][pre]表示还有pos位且前一位数字是pre非限制条件下为漂亮数字的个数。

#pragma comment(linker,"/STACK:1024000000,1024000000")

#include <cstdio>

#include <cstring>

#include <string>

#include <cmath>

#include <limits.h>

#include <iostream>

#include <algorithm>

#include <queue>

#include <cstdlib>

#include <stack>

#include <vector>

#include <set>

#include <map>

#define LL long long

#define mod 100000000

#define inf 0x3f3f3f3f

#define eps 1e-6

#define N 410

#define lson l,m,rt<<1

#define rson m+1,r,rt<<1|1

#define PII pair<int,int>

using namespace std;

inline LL read()

{

    char ch=getchar();LL x=0,f=1;

    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}

    while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}

    return x*f;

}

LL dp[15][15];

int dig[15];

LL dfs(int pos,int pre,int limit,int fzore)

{

    if(!pos)return 1;

    if(!limit&&~dp[pos][pre])return dp[pos][pre];

    LL ans=0;

    int len=limit?dig[pos]:9;

    for(int i=0;i<=len;i++)

    {

        if(fzore)

        {

            ans+=dfs(pos-1,i,i==len&&limit,fzore&&!i);

        }

        if(i>pre||i==0)continue;

        if(pre%i==0)

        {

            ans+=dfs(pos-1,i,i==len&&limit,0);

        }

    }

    if(!limit)dp[pos][pre]=ans;

    return ans;

}

LL solve(LL n)

{

    int len=0;

    while(n)

    {

        dig[++len]=n%10;

        n/=10;

    }

    return dfs(len,0,1,1);

}

int main()

{

    int T;

    LL a,b;

    T=read();

    memset(dp,-1,sizeof(dp));

    while(T--)

    {

        a=read();b=read();

        printf("%I64d\n",solve(b)-solve(a-1));

    }

}
View Code

 





你可能感兴趣的:(HDU)