蒟蒻的数位DP专题总结
BZOJ 1026: [SCOI2009]windy数:
题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=1026
dp[11][11][2]:dep,pre,f
要求的性质就是相邻数字差至少是2。
递归函数的状态设计如下dep,pre,f,分别表示已经枚举到第dep位,他的前一位(更高的位)是pre,f表示大小关系是否已经确定.
/// #include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define pb push_back
inline ll read()
{
ll x=,f=;char ch=getchar();
while(ch<''||ch>''){
if(ch=='-')f=-;ch=getchar();
}
while(ch>=''&&ch<=''){
x=x*+ch-'';ch=getchar();
}return x*f;
}
//****************************************
const int N=+;
#define mod 1000000007
#define inf 10000007 int dp[][][],vis[][][],d[];
int dfs(int dep,int pre,int f) {
if(dep<) return ;
else if(pre>=&&vis[dep][pre][f]) return dp[dep][pre][f];
else {
int re=;
if(pre == -) {
re+=dfs(dep-,-,f||d[dep]>);
if(f) for(int i=;i<=;i++) re+=dfs(dep-,i,);
else {
for(int i=;i<=d[dep];i++) {
re+=dfs(dep-,i,i<d[dep]);
}
}
}
else {
if(f) {
for(int i=;i<;i++) {
if(abs(i-pre)>) {
re+=dfs(dep-,i,);
}
}
}
else {
for(int i=;i<;i++) {
if(i<=d[dep]&&abs(i-pre)>) {
re+=dfs(dep-,i,i<d[dep]);
}
}
}
}
if(pre>=) vis[dep][pre][f]=,dp[dep][pre][f]=re;
return re;
}
}
int cal(int n) {
mem(dp);mem(vis);
int len=;
while(n) {
d[len++]=n%;n/=;
}
return dfs(len-,-,);
}
int main() {
int a,b;
while(scanf("%d%d",&a,&b)!=EOF) {
cout<<cal(b)-cal(a-)<<endl;
}
return ;
}
BZOJ1026
BZOJ 3209: 花神的数论题:
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3209
求的是1到N内进制种类数的个数的乘积,显然是数学题嘛。。。。
仔细想想:我们如果只考虑二进制上01的个数,也就是如果枚举1的个数,将二进制上含有i个1的个数用数位dp求解出来,再算快速幂,就可以得到答案了
/// #include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define pb push_back
inline ll read()
{
ll x=,f=;char ch=getchar();
while(ch<''||ch>''){
if(ch=='-')f=-;ch=getchar();
}
while(ch>=''&&ch<=''){
x=x*+ch-'';ch=getchar();
}return x*f;
}
//****************************************
const int N=+;
#define mod 10000007
#define inf 10000007
#define maxn 10000 ll dp[][][],vis[][][],d[N],c[N][N],ans[N];;
ll dfs(int dep,int left,int f) {
if(vis[dep][left][f]) return dp[dep][left][f];
if(dep+<left) return ;if(left==) return ;
ll& re=dp[dep][left][f];
vis[dep][left][f]=;
if(!f) {
if(d[dep]==) {
re+=dfs(dep-,left,f);
}
else {
re+=dfs(dep-,left,);
re+=dfs(dep-,left-,);
}
}
else {
re+=c[dep+][left];
}//vis[dep][left][f]=1,dp[dep][left][f]=re;
return re;
}
ll quick_pow(ll n,ll m) {
ll ret=;
while(m) {
if(m&) ret=(ret*n)%mod;
n=(n*n)%mod;
m>>=;
}
return ret;
}
ll cal(ll n) {
int len=;mem(vis);mem(dp);
while(n) {
d[len++]=n%;
n/=;
}
for (int i=;i<=len;i++) {
ans[i]=dfs(len-,i,);
}
ll A=;
for(int i=;i<=len;i++)A=(A*quick_pow(i,ans[i]))%mod;
return A;
}
int main(){
ll n;
for(int i=;i<=;i++) {
c[i][]=c[i][i]=;
for(int j=;j<i;j++) {
c[i][j]=c[i-][j]+c[i-][j-];
}
}
while(scanf("%lld",&n)!=EOF) {
printf("%lld\n",cal(n));
}
return ;
}
BZOJ3209
BZOJ 1799: [Ahoi2009]self 同类分布:
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1799
因为最多18位,最大也就是18*9,我们枚举位数和,去数位dp就可以了
/// #include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define pb push_back
inline ll read()
{
ll x=,f=;char ch=getchar();
while(ch<''||ch>''){
if(ch=='-')f=-;ch=getchar();
}
while(ch>=''&&ch<=''){
x=x*+ch-'';ch=getchar();
}return x*f;
}
//****************************************
const int N=+;
#define mod 10000007
#define inf 10000007
#define maxn 10000 ll dp[][][][],vis[][][][];
int d[N];
ll dfs(int dep,int T,int f,int sum,int M) {
if(dep<) return T == && sum == M;
if(sum>M)return ;
if(vis[dep][T][sum][f]) return dp[dep][T][sum][f];
ll& re=dp[dep][T][sum][f];
vis[dep][T][sum][f]=;
if(f) {
for(int i=;i<=;i++) {
re+=dfs(dep-,(T*+i)%M,f,sum+i,M);
}
}
else {
for(int i=;i<=d[dep];i++) {
re+=dfs(dep-,(T*+i)%M,i<d[dep],sum+i,M);
}
}
return re;
} ll cal(ll x) {
int len=;
ll A=;
while(x) d[len++]=x%,x/=;
for(int i=;i<=*len;i++) {
mem(dp),mem(vis);
A+=dfs(len-,,,,i);
}
return A;
}
int main() {
ll l,r;
while(scanf("%I64d%I64d",&l,&r)!=EOF) {
printf("%I64d\n",cal(r)-cal(l-));
//cout<<cal(r)-cal(l-1)<<endl;
}
return ;
}
BZOJ1799
HDU 4734 F(x):
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4734
我们先求出F(A),题意只要求满足F(x)<=F(A) 的就行,所以我们从构造数位dp 将F(A)设为上限,
F(A)可以发现最大就是9*2^9多一点,我们再枚举一个数位大小的时候,将剩余上限减去使用当前数位的F()贡献
最后也就是枚举完,剩余>=0就可行
/// #include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define pb push_back
inline ll read()
{
ll x=,f=;char ch=getchar();
while(ch<''||ch>''){
if(ch=='-')f=-;ch=getchar();
}
while(ch>=''&&ch<=''){
x=x*+ch-'';ch=getchar();
}return x*f;
}
//****************************************
const int N=+;
#define mod 10000007
#define inf 10000007
#define maxn 10000 int dp[][N],vis[][N],d[]; int dfs(int dep,int sum,int f) {
if(sum<) return ;
if(dep<) return sum>=;
if(f&&vis[dep][sum]) return dp[dep][sum];
if(f) {
int& re=dp[dep][sum];
vis[dep][sum]=;
for(int i=;i<=;i++) {
re+=dfs(dep-,sum-i*(<<dep),f);
}
return re;
}
else {
int re=;
for(int i=;i<=d[dep];i++) {
re+=dfs(dep-,sum-i*(<<dep),i!=d[dep]);
}
return re;
}
}
int cal(int A,int B) {
if(B==) return ;
int sum=;int len=;//mem(dp),mem(vis);
while(A) sum+=(A%)*(<<len),len++,A/=;
len=;
while(B) d[len++]=B%,B/=;
return dfs(len-,sum,);
} int main() {
int T=read();
int A,B;
for(int i=;i<=T;i++) {
A=read(),B=read();
printf("Case #%d: ",i);
printf("%d\n",cal(A,B));
}
return ;
}
HDU4734
HDU 3555 Bomb:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555
求1到N内有49相连的数字个数,经典数位;
/// #include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define pb push_back
inline ll read()
{
ll x=,f=;char ch=getchar();
while(ch<''||ch>''){
if(ch=='-')f=-;ch=getchar();
}
while(ch>=''&&ch<=''){
x=x*+ch-'';ch=getchar();
}return x*f;
}
//****************************************
const int N=+;
#define mod 10000007
#define inf 10000007
#define maxn 10000 ll dp[][],vis[][],d[];
ll dfs(int dep,int pre,int f) {
if(dep<) return ;
if(f&&vis[dep][pre]) return dp[dep][pre];
if(f) {
ll& re=dp[dep][pre];
vis[dep][pre]=;
for(int i=;i<=;i++) {
if(pre!=||(pre==&&i!=)) {
re+=dfs(dep-,i,f);
}
}return re;
}
else {
ll re=;
for(int i=;i<=d[dep];i++) {
if(pre!=||(pre==&&i!=))
re+=dfs(dep-,i,i<d[dep]);
} return re;
}
}
ll cal(ll x) {
int len=;mem(dp),mem(vis);
while(x) d[len++]=x%,x/=;
return dfs(len-,,);
}
int main() { int T=read();
while(T--) {
ll n;
scanf("%I64d",&n);
cout<<n-cal(n)+<<endl;
}
return ;
}
HDU3555
HDU 3709 Balanced Number:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3709
我们枚举平衡点就OK,注意0 的次数重复计算了,减去len-1就是答案
/// #include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define pb push_back
inline ll read()
{
ll x=,f=;char ch=getchar();
while(ch<''||ch>''){
if(ch=='-')f=-;ch=getchar();
}
while(ch>=''&&ch<=''){
x=x*+ch-'';ch=getchar();
}return x*f;
}
//****************************************
const int N=+;
#define mod 10000007
#define inf 10000007
#define maxn 10000 ll dp[][][],vis[][][],d[N];
ll dfs(int dep,int D,int mid,int f) {
if(dep<) return D==;
if(f&&vis[dep][D][mid]) return dp[dep][D][mid];
if(f) {
vis[dep][D][mid]=;
ll& re=dp[dep][D][mid];
for(int i=;i<=;i++) {
re+=dfs(dep-,D-(dep-mid)*i,mid,f);
}
return re;
}
else {
ll re=;
for(int i=;i<=d[dep];i++) {
re+=dfs(dep-,D-(dep-mid)*i,mid,i<d[dep]);
}
return re;
} }
ll cal(ll x) {
if(x==) return ;
if(x<) return ;
int len=;ll re=;mem(dp),mem(vis);
while(x) d[len++]=x%,x/=;
for(int i=;i<len;i++) {
re+=dfs(len-,,i,);
}
return re-len+;
}
int main() { int T=read();
while(T--) {
ll l,r;
scanf("%I64d%I64d",&l,&r);
cout<<cal(r)-cal(l-)<<endl;
}
return ;
}
HDU3709
蒟蒻的数位DP专题总结的更多相关文章
- 数位DP专题
这周开始刷数位DP,在网上找到一份神级数位DP模板,做起题目来爽歪歪. http://www.cnblogs.com/jffifa/archive/2012/08/17/2644847.html in ...
- 「动态规划」-数位dp专题
数位dp,今天学长讲的稍玄学,课下花了一会时间仔细看了一下,发现板子是挺好理解的,就在这里写一些: 数位dp主要就是搞一些在区间中,区间内的数满足题目中的条件的数的个数的一类题,题目一般都好理解,这时 ...
- 蒟蒻的树形dp记录
POJ2342: 题意:某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知每个人的活跃指数和上司关系(当然不可能存在环),求邀请哪些人(多 ...
- 蒟蒻所见之DP
本文有错是正常的,因为这只是一部成长史,并非教学博文. 会常年更下去. 2019.10.24 DP,核心只是"表格法"而已. DP题真正所考察的,是: 1.对问题的描述.简化以及归 ...
- 蒟蒻的trie树专题
POJ 3630 Phone List: 模板 ///meek #include<bits/stdc++.h> using namespace std; using namespace s ...
- hdoj2089(入门数位dp)
题目链接:https://vjudge.net/problem/HDU-2089 题意:给定一段区间求出该区间中不含4且不含连续的62的数的个数. 思路:这周开始做数位dp专题,给自己加油^_^,一直 ...
- 蒟蒻关于斜率优化DP简单的总结
斜率优化DP 题外话 考试的时候被这个玩意弄得瑟瑟发抖 大概是yybGG的Day4 小蒟蒻表示根本不会做..... 然后自己默默地搞了一下斜率优化 这里算是开始吗?? 其实我讲的会非常非常非常简单,, ...
- [kuangbin带你飞]专题十五 数位DP
ID Origin Title 62 / 175 Problem A CodeForces 55D Beautiful numbers 30 / 84 Problem B HD ...
- DP——由蒟蒻到神犇的进阶之路
开始更新咯 DP专题[题目来源BZOJ] 一.树形DP 1.bzoj2286消耗战 题解:因为是树形结构,一个点与根节点不联通,删一条边即可, 于是我们就可以简化这棵树,把有用的信息建立一颗虚树,然后 ...
随机推荐
- 用CSS样式写选择框右侧小三角
直接上代码! <!DOCTYPE html><html lang="en"><head> <title>小三角</title& ...
- 巧用Eclipse Java编辑器调试
在使用Eclipse开发Java Web应用时,使用的编辑器不但能够为开发者提供代码编写.辅助提示和实时编译等常用功能,而且还能够对Java源代码进行快捷修改.重构和语法纠错等高级操作.通过Eclip ...
- 背包系列 hdu 3535 分组背包
题意: 有n组工作,现在有T分钟时间去做一些工作.每组工作里有m个工作,并且类型为s,s类型可以为0,1,2,分别表示至少选择该组工作的一项,至多选择该工作的一项,不限制选择.每个工作有ci,gi两个 ...
- html——ico
下载: 网址+/favicon.ico 引用: 1.<link href="favicon.ico" rel="icon" /> 2.<lin ...
- Android中ViewPager动态创建的ImageView铺满屏幕
ImageView imageView=new ImageView(context); imageView.setScaleType(ScaleType.FIT_XY);//铺满屏幕
- Python标准库os
如果你希望自己的程序能够与平台无关的话,这个模块至关重要. os.name #'nt' for windows, 'posix' for linux/unix os.getcwd() #get cur ...
- Python之操作Excel、异常处理、网络编程
知识补充: 1.falsk模块中一些方法总结 import flask from flask import request,jsonify server = flask.Flask(__name__) ...
- [luogu2148 SDOI2009] E&D (博弈论)
传送门 Solution 我们知道当SG不为0则先手必胜,然后就可以打表了 ̄▽ ̄ Code //By Menteur_Hxy #include <cmath> #include <c ...
- Java 初学者
在有C++和C#基础之下开始学习Java,主要记录了一些和C++C#不同的或不知到的点 栈对象必须初始化,否则会报错.(其他的则有默认值) byte占用8位,char占用16位 接口默认为public ...
- 00.用 yield 实现 Python 协程
来源:Python与数据分析 链接: https://mp.weixin.qq.com/s/GrU6C-x4K0WBNPYNJBCrMw 什么是协程 引用官方的说法: 协程是一种用户态的轻量级线程,协 ...