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专题总结的更多相关文章

  1. 数位DP专题

    这周开始刷数位DP,在网上找到一份神级数位DP模板,做起题目来爽歪歪. http://www.cnblogs.com/jffifa/archive/2012/08/17/2644847.html in ...

  2. 「动态规划」-数位dp专题

    数位dp,今天学长讲的稍玄学,课下花了一会时间仔细看了一下,发现板子是挺好理解的,就在这里写一些: 数位dp主要就是搞一些在区间中,区间内的数满足题目中的条件的数的个数的一类题,题目一般都好理解,这时 ...

  3. 蒟蒻的树形dp记录

    POJ2342: 题意:某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知每个人的活跃指数和上司关系(当然不可能存在环),求邀请哪些人(多 ...

  4. 蒟蒻所见之DP

    本文有错是正常的,因为这只是一部成长史,并非教学博文. 会常年更下去. 2019.10.24 DP,核心只是"表格法"而已. DP题真正所考察的,是: 1.对问题的描述.简化以及归 ...

  5. 蒟蒻的trie树专题

    POJ 3630 Phone List: 模板 ///meek #include<bits/stdc++.h> using namespace std; using namespace s ...

  6. hdoj2089(入门数位dp)

    题目链接:https://vjudge.net/problem/HDU-2089 题意:给定一段区间求出该区间中不含4且不含连续的62的数的个数. 思路:这周开始做数位dp专题,给自己加油^_^,一直 ...

  7. 蒟蒻关于斜率优化DP简单的总结

    斜率优化DP 题外话 考试的时候被这个玩意弄得瑟瑟发抖 大概是yybGG的Day4 小蒟蒻表示根本不会做..... 然后自己默默地搞了一下斜率优化 这里算是开始吗?? 其实我讲的会非常非常非常简单,, ...

  8. [kuangbin带你飞]专题十五 数位DP

            ID Origin Title   62 / 175 Problem A CodeForces 55D Beautiful numbers   30 / 84 Problem B HD ...

  9. DP——由蒟蒻到神犇的进阶之路

    开始更新咯 DP专题[题目来源BZOJ] 一.树形DP 1.bzoj2286消耗战 题解:因为是树形结构,一个点与根节点不联通,删一条边即可, 于是我们就可以简化这棵树,把有用的信息建立一颗虚树,然后 ...

随机推荐

  1. MaBatis配置(单配置 之一)

    注: 此文中的实体类还是沿用上一章的Emp和Dept两个类 .引入需要的jar包文件:http://pan.baidu.com/s/1qYy9nUc :mybatis-3.2.2.jar .编写MyB ...

  2. Android 检查手机上是否安装了指定的软件(根据包名检测)

    Android检查手机上是否安装了指定的软件(根据包名检测) /** * 检查手机上是否安装了指定的软件 * @param context * @param packageName * @return ...

  3. 关闭掉eclipse启动的自动更新功能(提高打开eclipse的速度)

  4. JS——行内式注册事件

    html中行内调用function的时候,是通过window调用的function,所以打印this等于打印window,所以在使用行内注册事件时务必传入参数this <!DOCTYPE htm ...

  5. SQL server 2005中无法新建作用(Job)的问题

    1.在使用sqlserver2005创建作业时,创建不了,提示 无法将类型为“Microsoft.SqlServer.Management.Smo.SimpleObjectKey”的对象强制转换为类型 ...

  6. centOS Linux下用yum安装mysql

    centOS Linux下用yum安装mysql      第一篇:安装和配置MySQL   第一步:安装MySQL   [root@192 local]# yum -y install mysql- ...

  7. Maximum Value(unique函数,lower_bound()函数,upper_bound()函数的使用)

    传送门 在看大佬的代码时候遇到了unique函数以及二分查找的lower_bound和upper_bound函数,所以写这篇文章来记录以备复习. unique函数 在STL中unique函数是一个去重 ...

  8. Python之路【第一篇】:Python基础

    本节内容 Python介绍 发展史 Python 2 or 3? 安装 Hello World程序 变量 用户输入 模块初识 .pyc是个什么鬼? 数据类型初识 数据运算 表达式if ...else语 ...

  9. noip模拟赛 幻灯结界

    题目描述59式给你出了一道**题:有n个防御人(守方)还有n个攻击坦克(攻方)每个防御人有护甲a[i],而攻击方每个坦克有火力b[i]如果一个防守方的护甲不小于攻击方的攻击力,就可以防的住然而我们保持 ...

  10. 最小生成树prime算法模板

    #include<stdio.h> #include<string.h> using namespace std; int map[505][505]; int v, e; i ...