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

一,题意:

给定一个区间[n,m],要求求出该区间所有含4与62的数的个数。

二,解析:

这跟hdu3555,非常相似 ,介意先看hdu3555,看懂了hdu3555那么这题就是小菜了。

 hdu3555的详细解析在:点击打开链接

唯一不同是一个是要求包含 "49" 数的个数,一个是求不含 " 4 "和 " 62 "  数的个数,这只需要改变DFS边界就行了。

还有一个不同是两个题的区间不同。hdu3555 区间为[0,n],该题区间为[N,M]。我们处理[N,M]的方法是:

[N,M]=[0,M] - [0,N]即可。

三,代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
int N,M;
int dp[10][2];
int total[10];
int bit[10];

int DFS(int len,bool six,bool Max)
{
    if(len==0)
        return 1;//到达最后一层说明没有4或者62
    if(!Max&&dp[len][six]!=-1)
        return dp[len][six];
    int bian=9;
    if(Max)
        bian=bit[len];
    int sum=0;
    for(int i=0;i<=bian;i++)
    {
        if(i==4)//含有4就返回
            continue;
        if(six&&i==2)//含有62就返回
            continue;//剪枝
        sum+=DFS(len-1,i==6,Max&&(i==bit[len]));
    }
    if(!Max)
        dp[len][six]=sum;
    return sum;
}

int  solve(int n)
{
    int len=0;
    while(n)
    {
        bit[++len]=n%10;
        n=n/10;
    }
    return DFS(len,false,true);
}

int main()
{
    memset(dp,-1,sizeof(dp));
    while(scanf("%d%d",&N,&M)!=EOF&&(N||M))
    {
        memset(dp,-1,sizeof(dp));
        int x=solve(N-1);
        int y=solve(M);
        cout<<y-x<<endl;
    }
    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章