题目链接:

hdu: http://acm.hdu.edu.cn/showproblem.php?pid=5179

bc(中文): http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=569&pid=1002

题解:

1、数位dp

dp[i][j]表示第i位的数值为j的时候所有合法的情况,转移方程为dp[i][j]+=dp[i-1][k](j%k==0)数位最多为10位,可以离线处理出来。

计算1到x(x十进制按位存储在arr[]里面)的所有合法情况:

对于第i位,另前面几位等于arr[j](j>i),第i位为k<arr[i],则满足条件arr[i+1]%k==0的都是合法的,累加起来即可,然后考虑完i位之后,继续讨论i-1位,一直做下去。

0要单独讨论,假设x的长度为tot,则考虑最高位dp[tot-1][0](位数为第0位到第tot-1位)就是所有位数比tot小的合法数的总数,所以只要考虑最高位的0就可以了,其他位都不用考虑0。

区间[L,R]可以考虑为[1,R]-[1,L-1]。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; const int maxn = + ;
typedef long long LL; int a, b; LL dp[][];
void get_dp() {
memset(dp, , sizeof(dp));
dp[][] = ;
for (int i = ; i < ; i++) dp[][i] = ;
for (int i = ; i < ; i++) {
for (int j = ; j < ; j++) {
for (int k = ; k <= ; k++) {
if (j%k == ) {
dp[i][j] += dp[i - ][k];
}
}
if (j == ) dp[i][j] += dp[i - ][j];
}
}
} int arr[];
LL solve(int x) {
if (x == ) return ;
LL ret = ;
int tot = ;
memset(arr, , sizeof(arr));
while (x) {
arr[tot++] = x % ;
x /= ;
}
ret += dp[tot - ][];
for (int i = tot - ; i >= ; i--) {
if (arr[i] == ) break;
//表示从前几位不变第i位开始变小的所有合法数字
for (int j = arr[i] - ; j >= ; j--) {
if (arr[i + ] % j == ) {
ret += dp[i][j];
}
}
//最后一个数可以相等了,收尾了
if (i == && arr[i + ] % arr[i] == ) ret += dp[i][arr[i]];
//说明第i位不变的话就不可能合法了,不用继续做下去。
if (arr[i + ] % arr[i] != ) break;
}
return ret;
} int main() {
get_dp();
int tc;
scanf("%d", &tc);
while (tc--) {
scanf("%d%d", &a, &b);
LL ans = solve(b) - solve(a - );
printf("%lld\n", ans);
}
return ;
}

2、由于合法数不多,可以讨论离线暴力出一张表来,再二分答案。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std; const int maxn = + ;
typedef long long LL; const int tab[] = {
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
}; int solve(int x) {
if (x == ) return ;
return upper_bound(tab, tab+, x)-tab;
} int a, b; int main() {
int tc;
scanf("%d", &tc);
while (tc--) {
scanf("%d%d", &a, &b);
int ans = solve(b) - solve(a - );
printf("%d\n", ans);
}
return ;
}

3、上一发正规模板化数位dp

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf typedef int LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII; const int INF=0x3f3f3f3f;
const LL INFL=10000000000000000LL;
const double eps=1e-; const double PI = acos(-1.0); //start---------------------------------------------------------------------- LL dp[][];
int arr[],tot;
LL dfs(int len,int j, bool ismax,bool iszer) {
if (len == ) {
return 1LL;
}
if (!ismax&&dp[len][j]>=) return dp[len][j]; LL res = ;
int ed = ismax ? arr[len] : ;
for (int i = ; i <= ed; i++) {
if(iszer&&i==) {
res+=dfs(len-,,ismax&&i==ed,iszer&&i==);
} else {
if(i==) continue;
if(j==) {
res+=dfs(len-,i,ismax&&i==ed,iszer&&i==);
} else {
if(j>=i&&j%i==) {
res+=dfs(len-,i,ismax&&i==ed,iszer&&i==);
}
}
} }
return ismax ? res : dp[len][j] = res;
} LL solve(LL x) {
tot = ;
while (x) {
arr[++tot] = x % ;
x /= ;
}
return dfs(tot,,true,true);
} int main() {
clr(dp,-);
int tc,kase=;
scf("%d",&tc);
while(tc--) {
LL l,r;
scf("%d%d",&l,&r);
prf("%d\n",solve(r)-solve(l-));
}
return ;
} //end-----------------------------------------------------------------------

HDU 5179 beautiful number 数位dp的更多相关文章

  1. HDU 5179 beautiful number (数位dp / 暴力打表 / dfs)

    beautiful number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  2. hdu 5179 beautiful number(数位dp)

    原题链接 题意:求[l,r]中高位%低位等于0的数字个数.(不含0)分析:此题有三种方法.1.暴搜,毕竟最多才10个位.2.数位dp,预处理好整体的,再处理细节. dp[i][j]表示第i位上的数字位 ...

  3. hdu 5898 odd-even number 数位DP

    传送门:hdu 5898 odd-even number 思路:数位DP,套着数位DP的模板搞一发就可以了不过要注意前导0的处理,dp[pos][pre][status][ze] pos:当前处理的位 ...

  4. beautiful number 数位DP codeforces 55D

    题目链接: http://codeforces.com/problemset/problem/55/D 数位DP 题目描述: 一个数能被它每位上的数字整除(0除外),那么它就是beautiful nu ...

  5. hdu 5179 beautiful number

    beautiful number 问题描述 令 A = \sum_{i=1}^{n}a_i * {10}^{n-i}(1\leq a_i \leq 9)A=∑​i=1​n​​a​i​​∗10​n−i​ ...

  6. HDU 5787 K-wolf Number 数位DP

    K-wolf Number Problem Description   Alice thinks an integer x is a K-wolf number, if every K adjacen ...

  7. HDU 3709 Balanced Number (数位DP)

    Balanced Number Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) ...

  8. hdu 5898 odd-even number(数位dp)

    Problem Description For a number,if the length of continuous odd digits is even and the length of co ...

  9. HDU 5898 odd-even number (数位DP) -2016 ICPC沈阳赛区网络赛

    题目链接 题意:一个数字,它每个数位上的奇数都形成偶数长度的段,偶数位都形成奇数长度的段他就是好的.问[L , R]的好数个数. 题解:裸的数位dp, 从高到低考虑每个数位, 状态里存下到当前位为止的 ...

随机推荐

  1. 修复支付宝后台报错session IP change to many

    在项目的web.xml 中添加: <init-param> <param-name>sessionStatEnable</param-name> <param ...

  2. 1、win10下的Docker+Redis 的下载及简单使用

    一.下载Docker: 因为始终注册docker账号不成功,所以在这里点击下载. 选中docker-for-windows/ 选中beta/ 下载这个.msi文件 二.安装 1.安装.msi文件,桌面 ...

  3. keil编译运行错误,缺少error:#5:#include "core_cm3.h"

    用Keil  vision5编译时出现以下错误:error:  #5: cannot open source input file "core_cm3.h": No such fi ...

  4. 有限差分法解矩形波导内场值、截止频率 MATLAB

    利用有限差分法,解矩形波导内场解和截止频率: 这里以解TM11模为例,利用双重迭代法,每4次场值,更新一次Kc: %% % 求矩形波导中TM11模 截面内场分布.截止频率kc和特性阻抗Zc % // ...

  5. 阻止Quartus优化掉信号

    使用SignalTap II Logic Analyzer观察信号,有时要观察的信号会被Quartus优化掉,这种情况下可以给信号指定属性.以下例子均使用Verilog. 1. 如果是组合逻辑信号,可 ...

  6. 20155218 《Java程序设计》实验一(Java开发环境的熟悉)实验报告

    20155218 <Java程序设计>实验一(Java开发环境的熟悉)实验报告 一.实验内容及步骤 (一)使用JDK编译.运行简单的java程序 实验结果截图: (二)使用IDEA编辑.编 ...

  7. 20155325实验四 Android程序设计

    实验四 Android程序设计-1 Android Stuidio的安装测试: 参考<Java和Android开发学习指南(第二版)(EPUBIT,Java for Android 2nd)&g ...

  8. 20155329实验二 Java面向对象程序设计

    实验二 Java面向对象程序设计 1实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 2. 初步掌握单元测试 ...

  9. TCP三次握手和四次挥手以及11种状态

    1.三次握手 置位概念:根据TCP的包头字段,存在3个重要的标识ACK.SYN.FIN ACK:表示验证字段 SYN:位数置1,表示建立TCP连接 FIN:位数置1,表示断开TCP连接 三次握手过程说 ...

  10. Objective-C 方法交换实践(二) - 方法指针交换

    一. 基本函数 根据 sel 得到 class 的实例方法 Method class_getInstanceMethod(Class cls, SEL name) 根据 sel 得到 class 的函 ...