百度之星Valley Numer
Problem Description
众所周知,度度熊非常喜欢数字。
它最近发明了一种新的数字:Valley Number,像山谷一样的数字。
当一个数字,从左到右依次看过去数字没有出现先递增接着递减的“山峰”现象,就被称作 Valley Number。它可以递增,也可以递减,还可以先递减再递增。在递增或递减的过程中可以出现相等的情况。
比如,1,10,12,212,32122都是 Valley Number。
121,12331,21212则不是。
度度熊想知道不大于N的Valley Number数有多少。
注意,前导0是不合法的。
Input
第一行为T,表示输入数据组数。
每组数据包含一个数N。
● 1≤T≤200
● 1≤length(N)≤100
Output
对每组数据输出不大于N的Valley Number个数,结果对 1 000 000 007 取模。
Sample Input
3
3
14
120
Sample Output
3
14
119
很裸的一个数位DP,第一个切的就是这题。。
但是我还是只会写深搜版本啊,正统DP版不会。。但是深搜好写的
#include<cstdio>
#include<cstring>
typedef long long LL;
const int MOD=1000000007;
char ss[105];
LL yy[105][3][3][3][15];
int n;
LL dfs (int now,bool a,bool b,bool c,int last)
//当前到第几位 是否出现了小 是否已经是递增 是否已经有第一个非0位 上一个是什么
{if (now>n) return 1;if (yy[now][a][b][c][last]!=-1) return yy[now][a][b][c][last];int lalal=ss[now]-'0';//这一位是什么LL ans=0;if (c==false)//前面都是0{if (now==1)//还是第一位,不可以乱填 {ans=ans+dfs(now+1,true,false,false,0);ans%=MOD;for (int u=1;u<lalal;u++){ans=ans+dfs(now+1,true,false,true,u);ans%=MOD;}ans=ans+dfs(now+1,false,false,true,lalal);ans%=MOD;}else//也就是我爱填什么填什么 {ans=ans+dfs(now+1,true,false,false,0);ans%=MOD;for (int u=1;u<=9;u++){ans=ans+dfs(now+1,true,false,true,u);ans%=MOD;}}}else{if (a==false)//不可以越界 {if (b==false)//还不是递增{ans=ans+dfs(now+1,false,last<lalal,c,lalal);//我们这一位先填一样的ans%=MOD;if (lalal>last){for (int u=0;u<=last;u++){ans=ans+dfs(now+1,true,false,c,u);ans%=MOD;}for (int u=last+1;u<lalal;u++){ans=ans+dfs(now+1,true,true,c,u);ans%=MOD;}}else for (int u=0;u<lalal;u++){ans=ans+dfs(now+1,true,false,c,u);ans%=MOD;}}else//已经是递增了,不可以减了 {for (int u=last;u<lalal;u++)//我要填什么{ans=ans+dfs(now+1,true,true,c,u);ans%=MOD;}if (lalal>=last){ans=ans+dfs(now+1,false,true,c,lalal);ans%=MOD;}}}else//已经可以越界了 {if (b==false)//目前还不是递增状态{for (int u=0;u<=9;u++)//填什么 {ans=ans+dfs(now+1,true,last<u,c,u);ans%=MOD;}}else//已经是递增 {for (int u=last;u<=9;u++){ans=ans+dfs(now+1,true,true,c,u);ans%=MOD;}}}}yy[now][a][b][c][last]=ans;return ans;
}
int main()
{int T;scanf("%d",&T);while (T--){memset(yy,-1,sizeof(yy));scanf("%s",ss+1);n=strlen(ss+1);printf("%d\n",(dfs(1,false,false,false,0)%MOD-1+MOD)%MOD);}return 0;
}
百度之星Valley Numer相关推荐
- 2017百度之星复赛:1006. Valley Numer(数位DP)
Valley Numer Accepts: 548 Submissions: 1125 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: ...
- 2017 百度之星 复赛 Valley Numer(数位dp)
Valley Numer 数位dp,state标志前面若干位是否存在递增序列. 代码: #include <bits/stdc++.h> using namespace std;typed ...
- 2017百度之星程序设计大赛 - 复赛 01,03,05
Arithmetic of Bomb Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- HDU 6148 Valley Numer (数位dp)
题意: 求区间内满足非波峰数的个数. 其中波峰 是 先上升 在 下降, 平滑不会影响前面的状态. 思路: 很明显数位dp 令dp[i][j][k] 表示 枚举到数的第i 位, 前一个数字是j ...
- HDU 6148 Valley Numer(数位DP)
Valley Numer Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...
- HDU 6148 - Valley Numer(数位DP)
Valley Numer Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...
- 百度之星试题每周一练
百度之星,是全球最大的中文搜索引擎,百度公司面向中国高校学生和编程爱好者所举办的高水平的程序设计大赛.他所考试的题目,全部都是算法的题目. 鄙人虽然是一个.net程序员,在工作之余,喜爱算法. 这个问 ...
- 2011百度之星初赛B圆环
这是百度之星2011初赛B中的第一道题,题目也很水,只要找到解题思路就OK了.. 题目: 时间限制:1000ms 描述 一个圆环上有n个位置,这n个位置按顺时针依次标号为1, 2, -, n.初始时圆 ...
- 二分搜索 2015百度之星初赛1 HDOJ 5248 序列变换
题目传送门 1 /* 2 二分搜索:在0-1e6的范围找到最小的max (ai - bi),也就是使得p + 1 <= a[i] + c or a[i] - c 3 比赛时以为是贪心,榨干智商也 ...
最新文章
- 当下常用的webpack版本_细说 webpack系列 1. 为什么要选择 webpack
- 默认参数,不固定参数 *args,**kwargs
- 程序员面试什么最重要
- Java设计模式(八):外观设计模式
- 声腔设计中无前腔的影响
- 成功解决The scripts freeze_graph.exe, saved_model_cli.exe, tensorboard.exe, tflite_convert.exe, toco.exe
- matlab人工势场法三维演示图,人工势场法(Artificial Potential Field Method)的学习
- 3.1.4 操作系统之内存的分配与回收
- LDA主题模型原文解读
- 美国计算机授课型硕士,美国高校一年制硕士项目中,哪些项目最值得推荐?
- LeetCode:Balanced Binary Tree
- Java API下载和查阅方法
- Java 垃圾回收机制
- 下载oracle环境变量失败,oracle instantClient 安装配置及Error: DPI-1047: Cannot locate a 64-bit Oracle Client...
- 通过使用autoruns、procexp、currports相结合,来提高检查效率,清除干净木马病毒。
- 表面缺陷检测:机器视觉检测技术
- matlab 阿伦方差,GitHub - XinLiGH/GyroAllan: 陀螺仪随机误差的 Allan 方差分析
- docker 假死 僵尸状态
- python绘制多个散点图_绘制多个散点图熊猫
- Javascript-循环