题目链接:B-number

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

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
 

今天艾教讲了数位DP,自己硬着头皮写,竟然AC了,开心。

数位DP,dp[i][k]这两维是当前枚举到i,k是与给定的数比较,如果前i个数,正好等于给定的数,那么就是k就是1,否则就是0.举个栗子,比如给的最大的是236789.现在枚举到第三位6,如果前两个数是23,那么k=1,否则等于0.   然后对于本题还需两维,一维表示余数0-12,一维表示前面是否有13   d==2?(2):((d==1&&p==3)?2:((d==0&&p==1)?1:0) d =2表示前面已经有13了,d=1表示前面只有1,0表示其他。

初始化dp[0][0][1][0] = 1,对于这个,晚上我和翔哥讨论了一下午,为什么初始化这个dp[0][0][1][0],或者为什么初始化1.最后对所有dp[n]的数求和,比如给的数是1300,那么求和后得到是1301,数位dp把1300分成了许多集合,满足这个条件的在一个集合,满足那个条件的在那个集合。为什么多一,翔哥自己迷迷糊糊的在分析,我也听的迷迷糊糊,如果有大神路过,希望留下解释,谢谢!

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int mod = ;
int dp[][][][];
char s[];
int mi[];
int cal(int x,int wei,int p)
{
return x*mi[wei]%p;
}
int main()
{
mi[]=;
for (int i=;i<=;i++)
mi[i]=mi[i-]*%;
while(scanf("%s",s)!=EOF)
{
int n = strlen(s);
memset(dp,,sizeof(dp));
dp[][][][] = ;
for(int i=;i<n;i++)
{
for(int j=;j<=;j++)
{
for(int k=;k<=;k++)
{
for(int d=;d<=;d++)
{
if(dp[i][j][k][d]!=)
{
int l = ;
int r = (k==)?s[i]-'':;
for(int p=l;p<=r;p++)
{
dp[i+][(j+cal(p,n-i-,))%][(k==&&p==r)?:][d==?():((d==&&p==)?:(((d==||d==)&&p==)?:))]
+= dp[i][j][k][d];
/* if((i+1==4&&(j+cal(p,n-i-1,13))%13==0&&((k==1&&p==r)?1:0)==1&&(d==2?(2):((d==1&&p==3)?2:((d==0&&p==1)?1:0)))==2)||(i+1==4 && (j+cal(p,n-i-1,13))%13==0 && ((k==1&&p==r)?1:0==0) &&(d==2?(2):((d==1&&p==3)?2:((d==0&&p==1)?1:0)))==2))
printf("dp[%d][%d][%d][%d] = %d\n",i+1,(j+cal(p,n-i-1,13))%13,(k==1&&p==r)?1:0,d==2?(2):((d==1&&p==3)?2:((d==0&&p==1)?1:0)),dp[i+1][(j+cal(p,n-i-1,13))%13][(k==1&&p==r)?1:0][d==2?(2):((d==1&&p==3)?2:((d==0&&p==1)?1:0))]);*/
// printf("%d dp[%d][%d][%d][%d] = %d dp[%d][%d][%d][%d] = %d\n", p,i,j,k,d,dp[i][j][k][d],i+1,(j+cal(p,n-i-1,13))%13,(k==1&&p==r)?1:0,d==2?(2):((d==1&&p==3)?2:((d==0&&p==1)?1:0)),dp[i+1][(j+cal(p,n-i-1,13))%13][(k==1&&p==r)?1:0][d==2?(2):((d==1&&p==3)?2:((d==0&&p==1)?1:0))]);//*/ }
}
}
}
}
}
/* int ans = 0;
for(int i = 0; i < 13; i ++)
for(int j = 0; j < 2; j++)
for(int k = 0; k < 3; k++)
ans+=dp[n][i][j][k];*/
printf("%d\n",dp[n][][][]+dp[n][][][]);
//printf("%d\n",ans);
}
return ;
}

HDU 3652(数位DP)的更多相关文章

  1. hdu 3652数位dp

    /* 数位dp 题意:找到1-n之间包括13这个子串而且可以整除13的数 解:刚開始dp[N][N][2]这里的2用来记录是否为13表示当前位是否为13,我把上一位为1当前位为13和上一位部位1 这样 ...

  2. [hdu 3652]数位dp解决数的倍数问题

    原以为很好的理解了数位dp,结果遇到一个新的问题还是不会分析,真的是要多积累啊. 解决13的倍数,可以根据当前余数来推,所以把当前余数记为一个状态就可以了. #include<bits/stdc ...

  3. HDU - 3652 数位DP 套路题

    题意:统计能被13整除和含有13的数的个数 解法没法好说的..学了前面两道直接啪出来了 PS.HDU深夜日常维护,没法交题,拿网上的代码随便对拍一下,输出一致 #include<bits/std ...

  4. hdu 4507 数位dp(求和,求平方和)

    http://acm.hdu.edu.cn/showproblem.php?pid=4507 Problem Description 单身! 依旧单身! 吉哥依旧单身! DS级码农吉哥依旧单身! 所以 ...

  5. hdu 4352 数位dp + 状态压缩

    XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  6. 2017中国大学生程序设计竞赛 - 网络选拔赛 HDU 6156 数位DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6156 题意:如题. 解法:数位DP,暴力枚举进制之后,就转化成了求L,R区间的回文数的个数,这个直接做 ...

  7. hdu:2089 ( 数位dp入门+模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 数位dp的模板题,统计一个区间内不含62的数字个数和不含4的数字个数,直接拿数位dp的板子敲就行 ...

  8. HDU 4352 XHXJ's LIS HDU(数位DP)

    HDU 4352 XHXJ's LIS HDU 题目大意 给你L到R区间,和一个数字K,然后让你求L到R区间之内满足最长上升子序列长度为K的数字有多少个 solution 简洁明了的题意总是让人无从下 ...

  9. hdu 3709 数位dp

    数位dp,有了进一步的了解,模板也可以优化一下了 题意:找出区间内平衡数的个数,所谓的平衡数,就是以这个数字的某一位为支点,另外两边的数字大小乘以力矩之和相等,即为平衡数例如4139,以3为支点4*2 ...

随机推荐

  1. how computer boot up?

    The power button activates the power supply in the PC, sending power to the motherboard and other co ...

  2. 自定义AccessDeniedHandler

    在Spring默认的AccessDeniedHandler中只有对页面请求的处理,而没有对Ajax的处理.而在项目开发是Ajax又是我们要常用的技术,所以我们可以通过自定义AccessDeniedHa ...

  3. sql-删除delete涉及到三个表,这个时候就要使用from,比如这样

    delete y from dbo.XZXK_BANJIE b ,YJDC_YELLOWRED_CONTENT y , dbo.XZXK_SHOULI s where b.shoulioid=s.sh ...

  4. win10怎么启用网络发现,网络发现已关闭怎么办

    脑和电脑之间传输文件的方式很多,其中一种就是使用局域网,在网络中我们的电脑应该可以被其他电脑发现是非常方便使用文件共享的,尤其是在使用家庭组网络的时候,那么win10里面怎么启用网络发现呢? 工具/原 ...

  5. 安卓常用 widget

    验证码 public class SpinnerImg extends ImageView { /** * 完成选择后启动另外一个spinner */ private ItemListener ite ...

  6. linux的学习系列 7---管道和过滤器

    有时候,我们可以把两个命令连起来使用,一个命令的输出作为另一个命令的输入,这就叫做管道.为了建立管道,需要在两个命令之间使用竖线(|)连接. 管道是Linux进程之间一种重要的通信机制:除了管道,还有 ...

  7. Flexigrid的API

    基本设定 width  table的长度(default:auto) height  table的宽度(default:200) striped   表格的线的表示(default:true) nov ...

  8. 更方便的函数回调——Lambda

    auto callbackFunc = [&](){ backHome(); }; []符号,表示要开始一个lambda函数: ()符号,里面填写函数的参数: 当想在lambda函数里使用外部 ...

  9. Ubuntu 9.10+ apache2.2 +Django的配置

    1.首先安装mod_python apt-get install libapache2-mod-python2.6 (Ubuntu 9.10默认安装的是python 2.6版,如果是2.5可改为 li ...

  10. 转:Web安全与Rational AppScan入门

    Web 应用的基础概念 在讨论 Web 应用安全之前,先简单介绍一下 Web 应用基础概念,这样便于理解为什么 Web 应用是脆弱的,容易受到攻击. 1. 什么是 Web 应用 Web 应用是由动态脚 ...