HDU - 2089 do 62 (basis digit dp)


The meaning of problems:
a range is given \ ((L, R & lt) \) , requires the calculation range is not satisfied wherein two consecutive 62, and does not contain a count of the 4 conditions.
Ideas:
found before with digital dp write their previous method of using violence passed .... (direct enumeration then in addition to more than 4 and 64) so obviously done a digital dp title, but then no impression digit dp ..
About digital dp: dp counted on a digital use generally is to count an interval \ ([l, r] \ ) within a few number satisfying the condition number.
Blog written in great detail here: digit entry dp
digital recording is generally dp: \ (dp [Number] [State] \) , i.e. the number of digits, and the corresponding state different topics.
A \ (Solve () \) function of the number of processing the read values of all the bits, coexist in an array.
Then \ (dfs (int \ space pos , int \ space pre, int \ space state, int \ space limit) \) recorded the first few digits metastasis enumerated, one of its former value, which is the current state , as well as the current bit enumeration limit.
Then look at the details on the code ... annotated

code:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int a[20];
int dp[20][2];
//对于一个数 N 找到从1 ~ N 的所有非法情况数目。
//当前位,前导位,状态数,上限
//state表示上一位是否为6
int dfs(int pos,int pre,int state,bool limit){
    if(pos==-1) return 1;//表示该数已经被取完
    if(!limit && dp[pos][state] != -1) return dp[pos][state];
    int up  = limit ? a[pos] : 9;//确定该状态最高上限位
    int tmp = 0 ;
    //枚举当前位
    for(int i=0;i<=up;i++){
        if(pre == 6&& i==2) continue;//非法情况
        if(i==4) continue ;
        tmp += dfs(pos-1,i,i==6,limit && i==a[pos]);
    }
    if(!limit) dp[pos][state] = tmp;
    return tmp;

}
int solve(int x){
    int pos = 0;
    //取该数的每一位
    while(x){
        a[pos++] = x % 10;
        x /= 10;
    }
    //位数,前导初始化-1..
    return dfs(pos-1,-1,0,true);
}
int main(){
    int l,r;
    while(~scanf("%d%d",&l,&r)&&l&&r){
        memset(dp,-1,sizeof(dp));
        //由于要包含l位置,所以减到l-1
        printf("%d\n",solve(r)-solve(l-1));
    }
}

Guess you like

Origin www.cnblogs.com/Tianwell/p/11411422.html