B-number [HDU 3652]

http://acm.hdu.edu.cn/showproblem.php?pid=3652

View Code
//dp[i][j][3]  //表示前i个字符,余数为j  //0 存在13,1前一个是1 ,2什么都没有
const int MM = 1111;
typedef __int64 int64;
#define debug puts("wrong")
#define mod 13
int N,M;
int num[MM], cnt;
int dp[11][15][3]; //0 have 13 // 1 pre=1 // 2 no

int dfs(int le,int r,int pre,bool less) { //less前一位是否取到最大e=less?num[le]:9
    if(le==-1) return pre==0 && r==0; //边界条件,特定题目
    if(!less && dp[le][r][pre]!=-1) return dp[le][r][pre]; 
    int res=0,d, e=less?num[le]:9;
    for(d=0;d<=e;d++) {
        int tmp=pre;
        if(tmp!=0) {
            if(pre==1 && d==1) tmp=1;
            else if(pre==1 && d==3) tmp=0;
            else if(pre==1 && d!=3 && d!=1) tmp=2;
            else if(pre==2 && d==1) tmp=1;
            else tmp=2;
        }
        res+=dfs(le-1,(r*10+d)%mod,tmp,less&&d==e);
    }
    if(!less) dp[le][r][pre]=res;
    return res;
}

int cal(int x) {
    for(cnt=0 ;x; num[cnt++]=x%10,x/=10);
    return dfs(cnt-1,0,2,true); 
}
void solve() {
    int i,j,k;
    printf("%d\n",cal(N));
}
int main() {
//    int ca; scanf("%d",&ca);
    memset(dp,-1,sizeof(dp));
    while(scanf("%d",&N)!=EOF) solve();
    return 0;
}

 

posted @ 2013-04-27 16:42  zhang1107  阅读(131)  评论(0编辑  收藏  举报