码迷,mamicode.com
首页 > 其他好文 > 详细

B-number HDU - 3652 数位dp

时间:2020-03-15 21:55:56      阅读:59      评论:0      收藏:0      [点我收藏+]

标签:memset   amp   ace   mod   namespace   hdu   eof   set   秦九韶   

//dp[i][j][0]表示i位数模13为j当前没有包含13并且最高位不为1的方案数;
//dp[i][j][1]表示i位数模13为j当前没有包含13并且最高位为1的方案数;
//dp[i][j][2]表示i位数模13为j当前包含13的方案数。
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 15
using namespace std;
int bit[N],dp[N][N][3];
//遍历到的位置,前面的位数%13的余数
//have: 是否有13
// 
int dfs(int pos,int mod,int have,int lim) 
{
    int num,ans,mod_x,have_x;
    if(pos<=0) 
        return mod==0&&have==2;
    if(!lim&&dp[pos][mod][have]!=-1)
        return dp[pos][mod][have];
    num=lim?bit[pos]:9;
    ans=0;
    for(int i=0; i<=num; i++) {
        //秦九韶算法 
        mod_x=(mod*10+i)%13;
        have_x=have;
        //如果前面前一位不是1
        //这一位是1
        //标记有1 
        if(have==0&&i==1) 
            have_x=1;
        //如果前一位是1
        //当前位不是1
        //那么就标记没有 
        if(have==1&&i!=1) 
            have_x=0;
        //如果前一位是1
        //当前位是3
        //也就是有13,标记有 
        if(have==1&&i==3) 
            have_x=2;
        //往下递归 
        ans+=dfs(pos-1,mod_x,have_x,lim&&i==num);
    }
    //只有不受限的时候,才记录答案 
    if(!lim) 
        dp[pos][mod][have]=ans;
    return ans;
}
int main() {
    int n,len;
    while(scanf("%d",&n)!=EOF) {
        memset(bit,0,sizeof(bit));
        memset(dp,-1,sizeof(dp));
        len=0;
        while(n)
        {
            bit[++len]=n%10;
            n/=10;
        }
        printf("%d\n",dfs(len,0,0,1));
    }
    return 0;
}

B-number HDU - 3652 数位dp

标签:memset   amp   ace   mod   namespace   hdu   eof   set   秦九韶   

原文地址:https://www.cnblogs.com/QingyuYYYYY/p/12500175.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!