蒟蒻的数位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消耗战 题解:因为是树形结构,一个点与根节点不联通,删一条边即可, 于是我们就可以简化这棵树,把有用的信息建立一颗虚树,然后 ...
随机推荐
- Recyclerview点击事件,更新item的UI+更新Recyclerview外的控件
项目中用到了Recyclerview,在第一行代码中学到了一种相对来说简单的点击事件方法,可是这种点击事件是在adapter中写的,没有教怎么更新item的ui和更新Recyclerview之外的控件 ...
- 六时车主 App iOS隐私政策
本应用尊重并保护所有使用服务用户的个人隐私权.为了给您提供更准确.更有个性化的服务,本应用会按照本隐私权政策的规定使用和披露您的个人信息.但本应用将以高度的勤勉.审慎义务对待这些信息.除本隐私权政策另 ...
- java 中String与StringBuilder 效率
之前印象中string与stringbuilder操作时,如果多次改变string就使用stringbuilder,效率会提高: 今天实际遇到了问题,亲身经历过之后,这性能不是一般的影响啊:不是同一个 ...
- Centos 编译安装Haproxy
一.环境介绍 1.Centos6 2. haproxy-1.4.25.tar.gz 二.安装 $ curl -O http://haproxy.1wt.eu/download/1.4/src/hapr ...
- Attention-based Model
一.Attention与其他模型 1.LSTM.RNN的缺点:输入的Memory长度不能太长,否则参数会很多. 采用attention可以输入长Memory,参数不会变多. 2.Sequence to ...
- C#学习笔记_08_面向对象
08_面向对象 面向对象:一种看待问题解决问题的思维方式,着眼点在于找到一个能够帮助我们解决问题的实体,然后委托这个实体来帮我们解决问题:(在面向对象之前你要有一个女朋友,否则代码会经常出现bug) ...
- Python中的可迭代对象/迭代器/For循环工作机制/生成器
本文分成6个部分: 1.iterable iterator区别 2.iterable的工作机制 3.iterator的工作机制 4.for循环的工作机制 5.generator的原理 6.总结 1.i ...
- <embed> 标签
<embed> 标签定义嵌入的内容,比如插件. <embed quality="high" bgcolor="#FFF" wmode=&quo ...
- css进阶----盒子模型,Reset CSS,css浮动,css定位,z-index属性
盒子模型 把页面上的每一个元素当成一个盒子 由内容,内边距,边框,外边距组成 盒子模型举例 <!DOCTYPE html> <html lang="en"> ...
- 【codeforces 515B】Drazil and His Happy Friends
[题目链接]:http://codeforces.com/contest/515/problem/B [题意] 第i天选择第i%n个男生,第i%m个女生,让他们一起去吃饭; 只要这一对中有一个人是开心 ...