【算法】数位DP

【题意】定义V-number为从左到看单位数字未出现先递增后递减现象的数字,求0~N中满足条件的数字个数。T<=200,lenth(n)<=100

【题解】百度之星2017复赛,作为送分题出现,拿来练数位DP模板了。

位数多,读入记得用字符串。

记忆化要将有关变量全部纳入。

需要取模的时候别习惯性写"+=",特别是竞速赛,改起来很难受。

-1的变量前加~就和0一样了。

最后自己造数据测试了一下,记忆化搜索的速度简直全面碾压递推啊!(从此坚定了信仰)

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
#define ll long long
using namespace std;
const ll maxn=,MOD=;
ll f[maxn][][],a[maxn],n; ll dfs(ll pos,ll state,ll limit,ll pre){
if(pos==-){if(~pre)return ;else return ;}
if(!limit&&~pre&&~f[pos][state][pre])return f[pos][state][pre];
ll up=limit?a[pos]:;
ll ans=;
for(int i=;i<=up;i++){
if(pre==-&&i==)ans=(ans+dfs(pos-,state,limit&&i==up,pre))%MOD;else
if(pre==-&&i!=)ans=(ans+dfs(pos-,state,limit&&i==up,i))%MOD;else
if(state==)ans=(ans+dfs(pos-,i>pre,limit&&i==up,i))%MOD;else
if(state==&&i>=pre)ans=(ans+dfs(pos-,state,limit&&i==up,i))%MOD;//取模!!!
}
if(!limit&&~pre)f[pos][state][pre]=ans;//记忆化:当前状态和pos,state,pre三者都有关系!!!
return ans;
}
char s[maxn];
int main(){
ll T;
scanf("%lld",&T);
memset(f,-,sizeof(f));
while(T--){
scanf("%s",s+);
n=strlen(s+);
for(int i=;i<=n;i++)a[n-i]=s[i]-'';
printf("%lld\n",dfs(n-,,,-));
}
return ;
}

递推有病啊……细节一大堆,对拍调了一个又一个的错误才AC了,呜呜呜。

主要细节在逐位确定的时候:

1.如果前面递增了,后面枚举数位就不准枚举比前面小的。

2.如果前面递增又递减了,直接退出。

3.如果前面不递增且该位不大于前一位,后面才能取递减的值。

数位DP的逐位递推都是根据高位信息确定低位信息的哦!能干很多事(我选择记忆化搜索QAQ)

#include<cstdio>
#include<cstring>
const int MOD=1e9+,maxn=;
int f[maxn][maxn][],ans,n,a[maxn];
int M(int x){return x>=MOD?x-MOD:x;}
void p(int &x,int y){x=(x+y>=MOD?x+y-MOD:x+y);}
void solve(){
for(int i=;i<n;i++)for(int j=;j<=;j++)p(ans,M(f[i][j][]+f[i][j][]));
for(int j=;j<a[n];j++)p(ans,M(f[n][j][]+f[n][j][]));
bool ok=;
for(int i=n-;i>=;i--){
for(int j=;j<a[i];j++)if(ok||j>=a[i+]){
if(ok&&j<=a[i+])p(ans,M(f[i][j][]+f[i][j][]));
else p(ans,f[i][j][]);
}
if(!ok&&a[i]<a[i+])break;
if(a[i]>a[i+])ok=;
}
}
char s[maxn];
int main(){
int T;scanf("%d",&T);int N=;
for(int j=;j<=;j++)f[][j][]=;
for(int i=;i<=N;i++){
for(int j=;j<=;j++){
for(int k=;k<=;k++){
if(j>k)p(f[i][j][],f[i-][k][]);
else p(f[i][j][],f[i-][k][]);
if(j>=k)p(f[i][j][],f[i-][k][]);
}
}
}
while(T--){
scanf("%s",s+);n=strlen(s+);
for(int i=;i<=n;i++)a[i]=s[n-i+]-'';a[n+]=;
for(int i=;i<=n+;i++)if(a[i]!=){
if(i==n+)n++;
a[i]++;for(int j=i-;j>=;j--)a[j]=;
break;
}
ans=;solve();
printf("%d\n",ans);
}
return ;
}

【HDU】6148 Valley Numer 数位DP的更多相关文章

  1. HDU 6148 Valley Numer (数位DP)

    题意:... 析:好久没写数位DP了,几乎就是不会了.... dp[i][last][s] 表示前 i 位上一位是 last,当前的状态是 s,0表示非上升,1 表示非下降,然后就很简单了,只有 0 ...

  2. 2017"百度之星"程序设计大赛 - 复赛1005&&HDU 6148 Valley Numer【数位dp】

    Valley Numer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  3. HDU 6148 Valley Numer (数位DP)题解

    思路: 只要把status那里写清楚就没什么难度T^T,当然还要考虑前导零! 代码: #include<cstdio> #include<cstring> #include&l ...

  4. HDU 6156 - Palindrome Function [ 数位DP ] | 2017 中国大学生程序设计竞赛 - 网络选拔赛

    普通的数位DP计算回文串个数 /* HDU 6156 - Palindrome Function [ 数位DP ] | 2017 中国大学生程序设计竞赛 - 网络选拔赛 2-36进制下回文串个数 */ ...

  5. hdu 5898 odd-even number 数位DP

    传送门:hdu 5898 odd-even number 思路:数位DP,套着数位DP的模板搞一发就可以了不过要注意前导0的处理,dp[pos][pre][status][ze] pos:当前处理的位 ...

  6. hdu 5106 Bits Problem(数位dp)

    题目链接:hdu 5106 Bits Problem 题目大意:给定n和r,要求算出[0,r)之间全部n-onebit数的和. 解题思路:数位dp,一个ct表示个数,dp表示和,然后就剩下普通的数位d ...

  7. HDU 2089 - 不要62 - [数位DP][入门题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 Time Limit: 1000/1000 MS (Java/Others) Memory Li ...

  8. HDU 5179 beautiful number 数位dp

    题目链接: hdu: http://acm.hdu.edu.cn/showproblem.php?pid=5179 bc(中文): http://bestcoder.hdu.edu.cn/contes ...

  9. [hdu 2089] 不要62 数位dp|dfs 入门

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 题意:求[n, m]区间内不含4和62的数字个数. 这题有两种思路,直接数位dp和dfs 数位d ...

随机推荐

  1. C语言 内存分配 地址 指针 数组 参数 实例解析

    . Android源码看的鸭梨大啊, 补一下C语言基础 ... . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/detai ...

  2. 对Android体系结构的理解--后续会补充

    1.最底层_硬件 任何Android设备最底层的硬件包括 显示屏, wifi ,存储设备 等. Android最底层的硬件会根据需要进行裁剪,选择自己需要的硬件. 2.Linux内核层 该层主要对硬件 ...

  3. 算法与数据结构实验题 4.1 伊姐姐数字 game

    ★实验任务 伊姐姐热衷于各类数字游戏,24 点.2048.数独等轻轻松松毫无压力.一 日,可爱的小姐姐邀请伊姐姐一起玩一种简单的数字 game,游戏规则如下: 一开始桌上放着 n 张数字卡片,从左到右 ...

  4. 深入理解Java之数据类型

    一.概述 我们通过编程解决一个具体问题时,首先要做的工作是用各种“数据结构”表示问题中的实体对象,而后才能着手研究描述具体业务逻辑的算法.这也正印证了”程序 = 数据结构 + 算法“.而这里的数据结构 ...

  5. iOS开发JOSNModel<optional>,<convertondemand>,<index>

    指定定义的key的类型 <optional>表示字段可选,例如 //链接字段是可选的,转换的时候允许link未空 @property (nonatomic,strong) NSString ...

  6. Zigbee安全基础篇Part.1

    原文地址: https://www.4hou.com/wireless/14211.html 导语:ZigBee是一种开源无线技术,用于低功耗嵌入式设备(无线电系统).本文探讨了ZigBee协议的可用 ...

  7. sublime Remote_encoding cp1252

    "remote_encoding": "cp1252",才能连接远程ftp

  8. VBA练习-打开文件,添加选中项,生成新表

    学习VBA,正好给财务制作一个小工具: Sub 打开人员信息表() Dim wb As Workbook, c As Integer Set wb = Workbooks.Open(, True) c ...

  9. bzoj1968 约数研究

    题意 令\(f(i)\)表示\(i\)的约数个数,求\(\Sigma^n_{i=1}f(i)\). 做法 我们直接算每个数的贡献,问题可以转化成每个数在\(1\)到\(n\)中有多少个倍数,累加答案. ...

  10. 【bzoj4278】[ONTAK2015]Tasowanie 贪心+后缀数组

    题目描述 给定两个数字串A和B,通过将A和B进行二路归并得到一个新的数字串T,请找到字典序最小的T. 输入 第一行包含一个正整数n(1<=n<=200000),表示A串的长度. 第二行包含 ...