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

HDU3652 B-number 数位DP第二题

时间:2017-11-01 12:15:54      阅读:135      评论:0      收藏:0      [点我收藏+]

标签:提交   i++   const   cst   提交代码   二次   数位   cal   and   

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

 

技术分享

 

HDU3652 B-number 数位DP第二题

标签:提交   i++   const   cst   提交代码   二次   数位   cal   and   

原文地址:http://www.cnblogs.com/hua-dong/p/7765560.html

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