B-number

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3257    Accepted Submission(s): 1819

Problem Description
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.
 
Input
Process till EOF. In each line, there is one positive integer n(1 <= n <= 1000000000).
 
Output
Print each answer in a single line.
 
Sample Input
13
100
200
1000
 
Sample Output
1
1
2
2
 
Author
wqb0039
 
Source
 
Recommend
lcy
这道题跟只是将不要62的那道题稍微变形了一下,dp[i][j][k]长度为i,对13取余为j的数。
dp[i][j][0]代表不含13的整数的个数
dp[i][j][1]代表不含13,且首位为3的整数的个数
dp[i][j][2]代表含有13的整数的个数
#include<iostream>
#include<cstdio>
#include<cstring> using namespace std; const int N=;
int md[N],dp[N][][]; void Init(){
md[]=;
for(int i=;i<N;i++)
md[i]=md[i-]*;
memset(dp,,sizeof(dp));
dp[][][]=;
for(int i=;i<N-;i++)
for(int j=;j<;j++){
for(int k=;k<;k++)
dp[i+][(j+md[i]*k)%][]+=dp[i][j][];
dp[i+][(j+md[i])%][]-=dp[i][j][];
dp[i+][(j+md[i]*)%][]+=dp[i][j][];
dp[i+][(j+md[i])%][]+=dp[i][j][];
for(int k=;k<;k++)
dp[i+][(j+md[i]*k)%][]+=dp[i][j][];
}
}
int solve(int x)
{
int s[],len=,xx=x;
while(x>)
{
s[++len]=x%;
x/=;
}
s[len+]=; //初始化前缀为0,0是没有任何影响的,后面一位可能会用到前面一位
// cout<<len<<endl;
int ans=,flag=;
int yy=,yyy=;
int answer;
for(int i=len;i>=;i--) //每次枚举的数是:上界前缀+i这一位的数字+符合要求的dp[i][j][k]
{
answer=ans;
for(int kk=;kk<s[i];kk++)
{ for(int j=;j<;j++)
{
if(( (yyy*+ kk)*md[i-] +j)%==) //i这一位上枚举的数字变化,就得判断
{
ans+=dp[i-][j][];
}
} }
if(flag) //如果前缀中有出现13,并且
{
// ans+=s[i]*dp[i-1][0];
for(int kk=;kk<s[i];kk++)
for(int j=;j<;j++)
{
if(( (yyy*+ kk)*md[i-] +j)%==)
{
ans+=dp[i-][j][];
}
}
}
//只考虑以len位置为i的开头的数
if(!flag && s[i]>)
{
// ans+=dp[i-1][1];//因为是大于号,所以低一位可以完全枚举,加上首位为3的个数
for(int j=;j<;j++)
{
if(( (yyy*+ )*md[i-] +j)%==)
{
ans+=dp[i-][j][];
}
}
}
//考虑前缀的影响
if(!flag && s[i+]== && s[i]>)
// ans+=dp[i][1];
{
for(int j=;j<;j++)
{
if(( ((yyy-s[i+]+)*+ )*md[i-] + j )%==)
{
ans+=dp[i-][j][];
}
}
}
if(s[i+]== && s[i]==)
{
flag=;
}
yyy=yyy*+s[i];
}
return ans;
}
int main(){ // freopen("test.txt","r",stdin);
//cout<<(0%13)<<endl;
Init();
int n;
while(~scanf("%d",&n)){
printf("%d\n",solve(n+));
}
return ;
}

小优化的代码:

已知(a+b)%13=0,已知a,求b;

1:(a+b)%13=0;

2:(a%13+b%13)%13=0;

3:(13-a%13)%13=b;(第二次再MOD13,是因为a有可能等于0)

#include<iostream>
#include<cstdio>
#include<cstring> using namespace std;
const int V=; const int mod=;
const int N=;
int md[N],dp[N][][]; void Init(){
md[]=;
for(int i=;i<N;i++)
md[i]=md[i-]*%;
memset(dp,,sizeof(dp));
dp[][][]=;
for(int i=;i<N-;i++)
for(int j=;j<;j++){
for(int k=;k<;k++)
dp[i+][(j+md[i]*k)%][]+=dp[i][j][];
dp[i+][(j+md[i])%][]-=dp[i][j][];
dp[i+][(j+md[i]*)%][]+=dp[i][j][];
dp[i+][(j+md[i])%][]+=dp[i][j][];
for(int k=;k<;k++)
dp[i+][(j+md[i]*k)%][]+=dp[i][j][];
}
} int solve(int x)
{
int s[],len=,xx=x;
while(x>)
{
s[++len]=x%;
x/=;
}
s[len+]=; //初始化前缀为0,0是没有任何影响的,后面一位可能会用到前面一位
// cout<<len<<endl;
int ans=,flag=;
int yy=,yyy=;
int answer;
for(int i=len;i>=;i--)
{
// ans+=(s[i]*dp[i-1][2]); //含4和62的个数
answer=ans;
int temp_mod;
for(int kk=;kk<s[i];kk++)
{
temp_mod = ( - ( (yyy * + kk) * md[i-] )% ) %;
ans+=dp[i-][temp_mod][] ;
if(flag) //如果前缀中有出现13,并且
ans+=dp[i-][temp_mod][];
if(!flag && kk==)
{
ans+=dp[i-][temp_mod][];
}
if(!flag && s[i+]== && kk==)
ans+=dp[i-][temp_mod][]; }
//只考虑以len位置为i的开头的数
if(s[i+]== && s[i]==)
{
flag=; }
yyy=yyy*+s[i];
// printf("%d\n",ans-answer);
}
return ans;
} int main()
{ // freopen("test.txt","r",stdin);
//cout<<(0%13)<<endl;
Init();
int n;
while(~scanf("%d",&n)){
printf("%d\n",solve(n+));
}
return ;
}

hdu3652(含有13且能被13整除的数)数位DP基础的更多相关文章

  1. CF .Beautiful numbers 区间有多少个数字是可以被它的每一位非零位整除。(数位DP)

    题意:数字满足的条件是该数字可以被它的每一位非零位整除. 分析:大概的思路我是可以想到的 , 但没有想到原来可以这样极限的化简 , 在数位dp 的道路上还很长呀 : 我们都知道数位dp 的套路 , 核 ...

  2. HDU 3652 区间有13并且这样整除13 的数量(数位DP)

    题目:求1-n的范围里含有13且能被13整除的数字的个数. 分析: dfs(len, num, mod, flag) mod记录数字对13取余后的值 len表示当前位数 num==0 不含13且上一位 ...

  3. HDU3652 B-number —— 数位DP

    题目链接:https://vjudge.net/problem/HDU-3652 B-number Time Limit: 2000/1000 MS (Java/Others)    Memory L ...

  4. 数位DP HDU3652

    B-number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  5. hdu3652(数位dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3652 题意:求1~n含有13且能被13整除的数的个数. 分析:数位dp,dp数组加一维来维护到pos位 ...

  6. 【Hdu3652】B-number(数位DP)

    Description 题目大意:求小于n是13的倍数且含有'13'的数的个数. (1 <= n <= 1000000000) Solution 数位DP,题目需要包含13,且被13整除, ...

  7. [Hdu3652]B-number(数位DP)

    Description 题目大意:求小于n是13的倍数且含有'13'的数的个数. (1 <= n <= 1000000000) Solution 数位DP,题目需要包含13,且被13整除, ...

  8. 【HDU3652】B-number 数位DP

    B-number Problem Description A wqb-number, or B-number for short, is a non-negative integer whose de ...

  9. hdu3652 B-number 数位DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3652 题意就是求区间内能被13整除并且包含”13“的数字的个数 感觉是比较中等的数位DP题目 我用的记 ...

随机推荐

  1. _063_Android_Android内存泄露

    深入内存泄露 Android应用的内存泄露,其实就是java虚拟机的堆内存泄漏. 当然,当应用有ndk,jni时,没有及时free,本地堆也会出现内存泄漏. 本文只是针对JVM内存泄漏应用,进行阐述分 ...

  2. 【POJ1149&BZOJ1280】PIGS(最大流)

    题意:Emmy在一个养猪场工作.这个养猪场有M个锁着的猪圈,但Emmy并没有钥匙. 顾客会到养猪场来买猪,一个接着一个.每一位顾客都会有一些猪圈的钥匙,他们会将这些猪圈打开并买走固定数目的猪. 所有顾 ...

  3. 【zTree】zTree根据后台数据生成树并动态设置前面的节点复选框的选中状态

    0.页面中准备树的ul <ul id="treeDemo10" class="ztree" style="display: none;" ...

  4. lightoj 1293 - Document Analyzer [ 两指针 + 字符串 ]

    传送门 1293 - Document Analyzer   PDF (English) Statistics Forum Time Limit: 3 second(s) Memory Limit: ...

  5. 免费第三方API平台整合

    各大平台免费接口,非常适用 http://developer.51cto.com/art/201412/458778.htm 绝对干货:供个人开发者赚钱免费使用的一些好的API接口http://www ...

  6. POJ3177,/3352.求最少添加多少边使无向图边双连通

    俩个题一样.tarjan算法应用,开始求桥,WA,同一个边双连通分量中low值未必都相同,不能用此来缩点.后来用并查集来判断,若不是桥,则在一个双连通分量中,并之,后边再查,将同一个双连通分量中的点通 ...

  7. python学习之-- redis模块操作 string

    redis 模块操作之--> String String:redis中的string在内存中按照一个key 对应一个 value来存储. 使用方法如下:set(name, value, ex=N ...

  8. oracle数据库 SQL语句、内置函数大全

    1.数值函数 函数 返回值 样例 显示 CEIL(n)      大于或等于数值n的最小整数 SELECT CEIL(10.6) FROM TABLE_NAME; 11 FLOOR(n)  小于等于数 ...

  9. asp.net core 集成JWT(一)

    [什么是JWT] JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案. JWT的官网地址:https://jwt.io/ 通俗地来讲,JWT是能代表用户身份的令牌,可以使用JWT ...

  10. 解决Coldfusion连接MySQL数据库的问题

    在连接MySQL时,出现了如下错误: Connections to MySQL Community Server are not supported. Please contact MySQL to ...