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;
}



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