数位DP(学习笔记)
时间:2019-09-25
本文章向大家介绍数位DP(学习笔记),主要包括数位DP(学习笔记)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
洛咕日报这篇博客写得很好,蒟蒻在这里学会了
摘自上面那篇博客的模板:不过我一般不记录\(st\)这个值,而是在\(pos>len\)时直接返回1,表示找到了一个合法的数.
ll dfs(int pos,int pre,int st,……,int lead,int limit){//记搜
if(pos>len) return st;//剪枝
if((dp[pos][pre][st]……[……]!=-1&&(!limit)&&(!lead))) return dp[pos][pre][st]……[……];//记录当前值
ll ret=0;//暂时记录当前方案数
int res=limit?a[len-pos+1]:9;//res当前位能取到的最大值
for(int i=0;i<=res;i++){
//有前导0并且当前位也是前导0
if((!i)&&lead) ret+=dfs(……,……,……,i==res&&limit);
//有前导0但当前位不是前导0,当前位就是最高位
else if(i&&lead) ret+=dfs(……,……,……,i==res&&limit);
else if(根据题意而定的判断) ret+=dfs(……,……,……,i==res&&limit);
}
if(!limit&&!lead) dp[pos][pre][st]……[……]=ret;//当前状态方案数记录
return ret;
}
ll part(ll x){//把数按位拆分
len=0;
while(x) a[++len]=x%10,x/=10;
memset(dp,-1,sizeof dp);//初始化-1(因为有可能某些情况下的方案数是0)
return dfs(……,……,……,……);//进入记搜
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%lld%lld",&l,&r);
if(l) printf("%lld",part(r)-part(l-1));//[l,r](l!=0)
else printf("%lld",part(r)-part(l));//从0开始要特判
}
return 0;
}
HDU-不要62
题意:每次给定\(n,m\)一对数,求\([n,m]\)内不含4也不含62的数的个数.\(0<=n<=m<=1e7.\)
分析:直接套模板就好了.记得要特判\(n=0\)的情况.
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define ll long long
using namespace std;
inline int read(){
int x=0,o=1;char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')o=-1,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*o;
}
int n,m,len;
int a[10],dp[10][10];
inline ll dfs(int pos,int pre,int lead,int limit){
if(pos>len)return 1;//找到了一个合法的数
if(dp[pos][pre]!=-1&&(!lead)&&(!limit))return dp[pos][pre];//记忆化搜索
int cnt=0,res=limit?a[len-pos+1]:9;
for(int i=0;i<=res;++i){//枚举当前pos数位上能填的数
if(i==4)continue;//数字中不能含4
if(pre==6&&i==2)continue;//也不能有62
if((!i)&&lead)cnt+=dfs(pos+1,0,1,limit&&(i==res));
else if(i&&lead)cnt+=dfs(pos+1,i,0,limit&&(i==res));
else cnt+=dfs(pos+1,i,0,limit&&(i==res));
}
return (!limit&&!lead)?dp[pos][pre]=cnt:cnt;
}
inline int part(int x){
len=0;while(x)a[++len]=x%10,x/=10;
memset(dp,-1,sizeof(dp));
return dfs(1,0,1,1);
}
int main(){
while(1){
n=read(),m=read();if(!n&&!m)break;
if(!n)printf("%d\n",part(m)-part(1)+1);//特判
else printf("%d\n",part(m)-part(n-1));
}
return 0;
}
原文地址:https://www.cnblogs.com/PPXppx/p/11584242.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Linux本机与服务器文件互传及Linux服务器文件上传下载命令写法
- linux利用read命令获取变量中的值
- 解决Centos7 安装腾达U12无线网卡驱动问题
- CentOS 6.5上编译安装Apache服务器的方法(最小化安装)
- 固定QPS压测模式探索
- Centos6 网络配置的实例详解
- centos6.5升级安装配置supervisor的教程
- Linux的路由表详细介绍
- Centos7.3下vsftp服务的安装方法
- 详解Linux 安装 JDK、Tomcat 和 MySQL(图文并茂)
- 浅析Linux root设置初始值的方法
- 详解 Linux中的关机和重启命令
- 数据分析入门系列教程-KNN原理
- Selenium自动化的JUnit参数化实践
- linux云主机安装pdo详细教程