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, 从高到低考虑每个数位, 状态里存下到当前位为止的 ...
随机推荐
- $.ajax(),$.get(),$.post()的区别,以及一些参数注意规则
$.ajax()方法和$.get(),$.post()方法的对比 $.ajax()方法是最完整的写法,可以完成所有的ajax请求(包含get类型和post类型) $.get()和$.post()都是简 ...
- 创建Podfile,添加类库,中途添加库指令
前提是你电脑已经安装了CocoaPods 1.打开终端 2.进入你的工程目录 cd /Users/...../CocoaPodsDemo 3. 创建Pods文件 touch Podfile 新建 ...
- ps加强总结
快捷键 1.ctrl+alt+z返回 2.ctrl+z撤销 3.ctrl+s保存 4.ctrl+shift+s另存为 5.shift是有序的选择 ctrl键是无序的选择 6.ctrl+g打组 ...
- vue-cli 3.0 豆瓣api接口使用element做分页
记录自己的学习 大佬绕道谢谢! 豆瓣即将上映接口:https://api.douban.com/v2/movie/coming_soon 本地跨域问题 看我之前的文章:https://www.cnbl ...
- 使用jdk生成自签发证书(过程总结)
前言: 最近在做华为NB-IoT接口开发,需要用到双向认证,就去学了一下. 然后我将过程总结了一下. 相关华为论坛链接:http://developer.huawei.com/ict/forum/th ...
- Django 中跨 app 创建外键、多对多引用的方法
问题描述 我的 Django 项目中有两个 app. 在 PersonalCenter app下的 models.py 下定义了一个 Footprint 类: 在 LoginAndRegister a ...
- SSM-CRUD入门项目——新增与校验
新增 分析: 在Index.jsp页面点击新增,弹出对话框(模态框) 数据库查询部门列表显示在模态框中 用户输入数据完成操作 我们先把模态框构建出来,并对新增按钮添加事件,点击按钮弹出模态框: < ...
- 20155325 实验三 敏捷开发与XP实践
实验三 敏捷开发与XP实践-1 http://www.cnblogs.com/rocedu/p/4795776.html, Eclipse的内容替换成IDEA 在IDEA中使用工具(Code-> ...
- 20155337 2016-2017-2《Java程序设计》课程总结
20155337 2016-2017-2<Java程序设计>课程总结 (按顺序)每周作业链接汇总 <我的第一篇随笔> <做中学> <Java程序设计>第 ...
- day5 二值化
1.otsu二值化 # coding=utf-8 import cv2 import numpy as np from matplotlib import pyplot as plt #1.读入图像 ...