Live2d Test Env

HDU3652 B-number 数位DP第二题

A wqb-number, or B-number for short, is a non-negative integer whose decimal form contains the sub- string "13" and can be divided by 13. For example, 130 and 2613 are wqb-numbers, but 143 and 2639 are not. Your task is to calculate how many wqb-numbers from 1 to n for a given integer n.

InputProcess till EOF. In each line, there is one positive integer n(1 <= n <= 1000000000).OutputPrint each answer in a single line.Sample Input

13
100
200
1000

Sample Output

1
1
2
2

心里没有点13数吗,233?

 

第一次提交代码:

 

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define LL long long
const int N=20;
int dp[N][N][2][2][2],n;
int a[N],cnt;
void _divide(LL v){
    cnt=0;
    while(v){a[++cnt]=v%10;v/=10;}
}
int _dfs(int pos,int Mod,bool limit,bool pre,bool stat)
{
     if(pos==0) return stat&&!Mod;
     int tmp=0;
     if(!limit&&dp[pos][Mod][limit][pre][stat]) return dp[pos][Mod][limit][pre][stat];
     int Up=limit?a[pos]:9;
     for(int i=0;i<=Up;i++)
         tmp+=_dfs(pos-1,(Mod*10+i)%13,limit&&i==Up,i==1,stat||(pre&&i==3));
     dp[pos][Mod][limit][pre][stat]=tmp;
     return tmp;
}
int main()
{
    int i,T;
    while(~scanf("%d",&n)){
        memset(dp,0,sizeof(dp));
        _divide(n);
        printf("%d\n",_dfs(cnt,0,true,false,false));
    }
    return 0;
}

 

 

 

 

 

 时间长,是因为memset次数太多。

优化:去掉memset,加上limit限制

第二次提交代码:

 

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define LL long long
const int N=20;
int dp[N][N][2][2][2],n;
int a[N],cnt;
void _divide(LL v){
    cnt=0;
    while(v){a[++cnt]=v%10;v/=10;}
}
int _dfs(int pos,int Mod,bool limit,bool pre,bool stat)
{
     if(pos==0) return stat&&!Mod;
     int tmp=0;
     if(!limit&&dp[pos][Mod][limit][pre][stat]) return dp[pos][Mod][limit][pre][stat];
     int Up=limit?a[pos]:9;
     for(int i=0;i<=Up;i++)
         tmp+=_dfs(pos-1,(Mod*10+i)%13,limit&&i==Up,i==1,stat||(pre&&i==3));
     dp[pos][Mod][limit][pre][stat]=tmp;
     return tmp;
}
int main()
{
    int i,T;
    while(~scanf("%d",&n)){
        _divide(n);
        printf("%d\n",_dfs(cnt,0,true,false,false));
    }
    return 0;
}

 

 

posted @ 2017-11-01 11:18  nimphy  阅读(184)  评论(0编辑  收藏  举报