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. IIS文件存在但报404问题解决

    遇到一个奇怪的问题,在IIS7.5中,一些样式和JS文件存在,但访问就是报404. 根据网上搜索到的解决方法,发现解决不了,不同同样的问题引起的. 网上解决: 1.没有配置合适的MIME信息,通过添加 ...

  2. CodeForces - 462B Appleman and Card Game

    是一道简单题 将字母从个数多到小排序 然后 再按题目算法得到最多 但是注意 数据类型声明 money要为long long #include <iostream> #include < ...

  3. [Usaco2009 Open]工作安排Job

    Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1457  Solved: 687[Submit][Status][Discuss] Descriptio ...

  4. Mongodb主、副、仲裁节点集群安装

    mongodb 的集群方式主要分为三种Replica Set / Sharding / Master-Slaver ,这里只说明最简单的集群搭建方式(生产环境),如果有多个节点可以此类推或者查看官方文 ...

  5. python学习之-- socketserver模块

    socketserver 模块简化了网络服务器的编写,主要实现并发的处理. 主要有4个类:这4个类是同步进行处理的,另外通过ForkingMixIn和ThreadingMixIn类来支持异步.sock ...

  6. Java日志框架-Logback手册中文版以及官方配置文档教程

    Logback手册中文版:(链接: https://pan.baidu.com/s/1bpMyasR 密码: 6u5c),虽然版本有点旧,但是大体意思差不多,先用中文版了解个大概,然后一切最新的配置以 ...

  7. leetCode 78.Subsets (子集) 解题思路和方法

    Given a set of distinct integers, nums, return all possible subsets. Note: Elements in a subset must ...

  8. WebApi-路由机制 Visual Studio 2015中的常用调试技巧分享

    WebApi-路由机制   一.WebApi路由机制是什么? 路由机制通俗点来说:其实就是WebApi框架将用户在浏览器中输入的Url地址和路由表中的路由进行匹配,并根据最终匹配的路由去寻找并匹配相应 ...

  9. centos7 64位系统jdbc连接oracle报错问题

    这两天发生了一个错误,记录下来. 报错如下: ### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could n ...

  10. PHP引用是什么?

    引用是什么 在 PHP 中引用意味着用不同的名字访问同一个变量内容.这并不像 C 的指针,替代的是,引用是符号表别名.注意在 PHP 中,变量名和变量内容是不一样的,因此同样的内容可以有不同的名字.最 ...