HDU 5179 beautiful number 数位dp
题目链接:
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的更多相关文章
- HDU 5179 beautiful number (数位dp / 暴力打表 / dfs)
beautiful number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 5179 beautiful number(数位dp)
原题链接 题意:求[l,r]中高位%低位等于0的数字个数.(不含0)分析:此题有三种方法.1.暴搜,毕竟最多才10个位.2.数位dp,预处理好整体的,再处理细节. dp[i][j]表示第i位上的数字位 ...
- hdu 5898 odd-even number 数位DP
传送门:hdu 5898 odd-even number 思路:数位DP,套着数位DP的模板搞一发就可以了不过要注意前导0的处理,dp[pos][pre][status][ze] pos:当前处理的位 ...
- beautiful number 数位DP codeforces 55D
题目链接: http://codeforces.com/problemset/problem/55/D 数位DP 题目描述: 一个数能被它每位上的数字整除(0除外),那么它就是beautiful nu ...
- hdu 5179 beautiful number
beautiful number 问题描述 令 A = \sum_{i=1}^{n}a_i * {10}^{n-i}(1\leq a_i \leq 9)A=∑i=1nai∗10n−i ...
- 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 ...
- HDU 3709 Balanced Number (数位DP)
Balanced Number Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) ...
- 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 ...
- HDU 5898 odd-even number (数位DP) -2016 ICPC沈阳赛区网络赛
题目链接 题意:一个数字,它每个数位上的奇数都形成偶数长度的段,偶数位都形成奇数长度的段他就是好的.问[L , R]的好数个数. 题解:裸的数位dp, 从高到低考虑每个数位, 状态里存下到当前位为止的 ...
随机推荐
- JAVA 设计模式之原型模式
目录 JAVA 设计模式之原型模式 简介 Java实现 1.浅拷贝 2.深拷贝 优缺点说明 1.优点 2.缺点 JAVA 设计模式之原型模式 简介 原型模式是六种创建型设计模式之一,主要应用于创建相同 ...
- 淘宝商品放大镜效果-JavaScript
效果图 HTML代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...
- 可编辑div中包含子元素时获取光标位置不准确的问题
前言: 高亮显示输入框中的关键字符,这就必须得用到可编辑div(或其他标签)元素了,这时我们需要获取光标的位置,以便插入字符. 正文: 正常情况下获取光标位置,代码如下: function getPo ...
- POJ3006-Dirichlet's Theorem on Arithmetic Progressions
题意: 设一个等差数列,首元素为a,公差为d 现在要求输入a,d,n ,要求找出属于该等差数列中的第n个素数并输出 思路:空间换时间是个主旋律.素数表的生成用素数筛选法.方法是从2开始,对每个目前还标 ...
- springboot(eureka子项目)+idea+jsp 404问题
我是这么解决的 对于单一项目,加入以下jar包即可 <!--前台页面的支持--> <dependency> <groupId>javax.servlet</g ...
- 20155236 《Java程序设计》实验四(Android程序设计)实验报告
20155236 <Java程序设计>实验四(Android程序设计)实验报告 一.实验内容及步骤 第24章:初识Android 任务一:完成Hello World, 要求修改res目录中 ...
- java 万能转换器 输入SQL 直接得到ArrayList
//java万能List转换器 public static <T> ArrayList<T> ToList(Class<T> clazz,String sql) t ...
- C#基础之接口
对于接口一直以来都清楚自己理解的不深入,这两天重温以前的代码时更加发现对接口的理解仅仅限于定义而已,得好好学学接口了. 1.接口的特点 接口的定义是指定一组函数成员而不实现成员的引用类型,其它类型和接 ...
- Linux系统运维基础管理命令总结
1.查看系统负载命令:w.uptime [root@localhost ~]# w :: up days, :, user, load average: 0.00, 0.01, 0.05 USER T ...
- Unity3D使用NGUI实现简单背包功能
前话 在许多类型游戏中我们经常会使用到背包,利用背包来设置相应角色属性,多了背包也会让游戏增色拓展不少. 那在Unity3D游戏开发中该如何编写背包系统呢?因为有高人开发了NGUI插件,因此我们进行简 ...