HDU 2089 数位dp入门

题目链接:(不要62)[http://acm.hdu.edu.cn/showproblem.php?pid=2089]
题解:f[i][j]表示长度为i最高位为j符合题意的个数。
根据题意可以推出状态方程;
 f[i][j]=

    if (j==4) f[i][j]=0

    else if (j!=6) f[i][j]=Σf[i-1][k] (k=0,1,2,3,4,5,6,7,8,9)

    else if (j==6) f[i][j]=Σf[i-1][k] (k=0,1,3,4,5,6,7,8,9)
然后用一个slove(int x)函数求出0到x的合法个数。具体过程看code

#include<bits/stdc++.h>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#define pb push_back
#define ll long long
#define PI 3.14159265
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define eps 1e-7
const int mod=100;
const int maxn=1e5+5;
using namespace std;
ll f[10][10];//f[i][j]
int a[10];
const int inf=0x3f3f3f3f3f3f3f;
int n,m;
void get_f()
{
    //for(int i=0;i<10)f[0][i]=1;
    f[0][0]=1;
    for(int i=1;i<10;i++)
    {

        for(int j=0;j<10;j++)
        {
            if(j==4)f[i][j]=0;
            else if(j==6)
            {
                for(int k=0;k<10;k++)
                {
                    if(k==2)continue;
                    f[i][j]+=f[i-1][k];
                }
            }
            else
            {
                for(int k=0;k<10;k++)
                {
                    f[i][j]+=f[i-1][k];
                }
            }
        }
    }
}
ll slove(int x)
{
    int pos=1;
    while(x)
    {
        a[pos++]=x%10;
        x/=10;
    }
    a[pos]=0;
    ll ans=0;
    for(int i=pos-1;i>=1;i--)
    {
        for(int j=0;j<a[i];j++)
        {
            if(j!=4&&!(a[i+1]==6&&j==2))
            ans+=f[i][j];
        }
        if(a[i]==4)break;
        if(a[i]==2&&a[i+1]==6)break;

    }
    return ans;
}
int main()
{
     std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    get_f();
    while(cin>>n>>m)
    {
        if(n==0&&m==0)
        {
            break;
        }
        cout<<slove(m+1)-slove(n)<<endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/lhclqslove/p/7954718.html