HDU 2089 不要62(数位dp入门)

题意:统计区间 [a,b] 中不含 4 和 62 的数字有多少个。

题解:这是数位DP的入门题了,首先要理解数DP的原理,DP[i][j]:代表第i位的第j值,举个栗子:如4715   数位数是从右向左的,则第一位是5,第二位是1,第三位是7,第四位是4。所以如果要求0到4715,ans=dp[4][x]+dp[3][y]+dp[2][z]+dp[1][k]

0<=x<=4(但是4要去掉),0<=y<=9,0<=z<=9,0<=k<=9(还要注意判断,把其中62,和4去掉)

AC代码:

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int INF=0x3f3f3f3f;
typedef long long ll;
typedef unsigned long long ull;
#define prN printf("
")
#define SI(N) scanf("%d",&(N))
#define SII(N,M) scanf("%d%d",&(N),&(M))
#define SIII(N,M,K) scanf("%d%d%d",&(N),&(M),&(K))
#define cle(a,val) memset(a,(val),sizeof(a))
#define rep(i,b) for(int i=0;i<(b);i++)
#define Rep(i,a,b) for(int i=(a);i<=(b);i++)
#define reRep(i,a,b) for(int i=(a);i>=(b);i--)
const int MAX_N= 1000+5 ;
const double eps= 1e-9 ;

int dp[10][10];
int sol(int n)
{
    int *dig=new int [10];
    int len=1;
    while(n)
    {
        dig[len++]=n%10;
        n/=10;
    }
    int ans=0;
    for (int i=len-1; i!=0; i--)
    {
        for (int j=0; j<dig[i]; j++)
        {
            if (j!=4&&!(dig[i+1]==6&&j==2))
                ans+=dp[i][j];
        }
        if (dig[i]==4||(dig[i]==2&&dig[i+1]==6))
            break;
    }
    return ans;
}

int main()
{
#ifndef ONLINE_JUDGE
//    freopen("C:\Users\Zmy\Desktop\in.txt","r",stdin);
//    freopen("C:\Users\Zmy\Desktop\out.txt","w",stdout);
#endif // ONLINE_JUDGE
    dp[0][0]=1;
    for (int i=1; i<=7; i++)
    {
        for (int j=0; j<=9; j++)
        {
            for (int k=0; k<=9; k++)
            {
                if (j!=4&&(j!=6||k!=2))
                {
                    dp[i][j]+=dp[i-1][k];
                }
            }
        }
    }
    int l,r;
    while(cin>>l>>r,l||r)
    {
        cout<<sol(r+1)-sol(l)<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/s1124yy/p/5533506.html