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. [POJ2594] Treasure Exploration(最小路径覆盖-传递闭包 + 匈牙利算法)

    传送门 引子: 有一个问题,是对于一个图上的所有点,用不相交的路径把他们覆盖,使得每个点有且仅属于一条路径,且这个路径数量尽量小. 对于这个问题可以把直接有边相连的两点 x —> y,建一个二分 ...

  2. 数列分段Section II(二分)

    洛谷传送门 输入时处理出最小的答案和最大的答案,然后二分答案即可. 其余细节看代码 #include <iostream> #include <cstdio> using na ...

  3. idea与eclipse项目相互导入的过程

    idea项目导出到桌面 很简单,直接去项目所在目录考出即可,但是考出的项目往往都特别大,这是因为考出之前  我们不要忘记把idea的输出目录删除 每次启动服务器运行idea项目的时候  都会有一个输出 ...

  4. redis哨兵模式配置

    java对redis的读写 依赖包:jedis.jar maven下: <!-- https://mvnrepository.com/artifact/redis.clients/jedis - ...

  5. FusionCharts for Flex 如何更改图表数据

    FusionCharts allows to change chart data and re-render the chart, after it has loaded on the user’s ...

  6. 【Java源码】集合类-ArrayList

    一.类继承关系 public class ArrayList<E> extends AbstractList<E> implements List<E>, Rand ...

  7. SD/MMC的Commands和Responses的总结

    SD总线通信是基于指令和数据比特流,起始位開始和停止位结束. SD总线通信有三个元素:1.Command:由host发送到卡设备.使用CMD线发送. 2.Response:从card端发送到host端 ...

  8. [转]用AOP改善javascript代码

    有时候,不光要低头写代码,也要学着站在更高的角度,来思考代码怎么写,下面这篇文章,讲的关于代码设计的问题,脑洞大开. 原文: http://www.alloyteam.com/2013/08/yong ...

  9. jquery 动态添加,降低input表单的方法

    html代码例如以下 <html> <tr><button style="margin-left:10px" class="add_fiel ...

  10. RxJava系列之中的一个 初识Rxjava

    1.简单介绍 基础知识 响应式代码的基本组成部分是Observables和Subscribers(事实上Observer才是最小的构建块,但实践中使用最多的是Subscriber.由于Subscrib ...