HDU 6148 Valley Numer(数位DP)

  1 #include <iostream>
  2 #include <queue>
  3 #include <stack>
  4 #include <cstdio>
  5 #include <vector>
  6 #include <map>
  7 #include <set>
  8 #include <bitset>
  9 #include <algorithm>
 10 #include <cmath>
 11 #include <cstring>
 12 #include <cstdlib>
 13 #include <string>
 14 #include <sstream>
 15 #include <time.h>
 16 #define x first
 17 #define y second
 18 #define pb push_back
 19 #define mp make_pair
 20 #define lson l,m,rt*2
 21 #define rson m+1,r,rt*2+1
 22 #define mt(A,B) memset(A,B,sizeof(A))
 23 using namespace std;
 24 typedef long long LL;
 25 typedef unsigned long long ull;
 26 //const double PI = acos(-1);
 27 const int N=3e3+10;
 28 const LL mod=1e9+7;
 29 const int inf = 0x3f3f3f3f3f;
 30 const LL INF=0x3f3f3f3f3f3f3f3fLL;
 31 const double eps=1e-8;
 32 LL dp[300][20][2][2];
 33 int num[300];
 34 char s[300];
 35 LL dfs(int pos,int pre,int limit,int flag,int zero)
 36 {
 37      LL res=0;
 38      if(pos<0)
 39      {
 40          if(zero)return 0;
 41          else return 1;
 42      }
 43      if(!limit&&dp[pos][pre][flag][zero]!=-1)return dp[pos][pre][flag][zero];
 44
 45      int top=limit?num[pos]:9;
 46      if(zero)
 47      {
 48          for(int i=0;i<=top;i++)
 49          {
 50              res=(res+dfs(pos-1,i,limit&&(num[pos]==i),0,i==0))%mod;
 51          }
 52      }
 53      else
 54      {
 55          if(flag)
 56          {
 57              for(int i=pre;i<=top;i++)
 58              {
 59                  res=(res+dfs(pos-1,i,limit&&(num[pos]==i),1,0))%mod;
 60              }
 61          }
 62          else
 63          {
 64              for(int i=min(pre,top);i>=0;i--)
 65              {
 66                  res=(res+dfs(pos-1,i,limit&&(num[pos]==i),0,0))%mod;
 67              }
 68              for(int i=pre+1;i<=top;i++)
 69              {
 70                  res=(res+dfs(pos-1,i,limit&&(num[pos]==i),1,0))%mod;
 71              }
 72          }
 73      }
 74
 75      if(!limit)dp[pos][pre][flag][zero]=res;
 76      return res;
 77 }
 78 void solve()
 79 {
 80      int n;
 81      mt(dp,-1);
 82      scanf("%s",s);
 83      n=strlen(s);
 84      for(int i=n-1,j=0;i>=0;i--,j++)num[j]=s[i]-‘0‘;
 85      printf("%lld\n",dfs(n-1,0,1,0,1));
 86 }
 87 int main()
 88 {
 89 #ifdef Local
 90     freopen("data.h","r",stdin);
 91     //freopen("out.txt","w",stdout);
 92 #endif
 93     //ios::sync_with_stdio(false);
 94     //cin.tie(0);
 95     //solve();
 96     int T,cas=1;
 97     cin>>T;
 98     while(T--)
 99     {
100         //printf("Case #%d: ",cas++);
101         solve();
102     }
103 #ifdef Local
104     cerr << "time: " << (LL) clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
105 #endif
106     return 0;
107 }

时间: 2024-10-12 08:58:10

HDU 6148 Valley Numer(数位DP)的相关文章

hdu 6148 Valley Numer (数位dp)

Problem Description 众所周知,度度熊非常喜欢数字. 它最近发明了一种新的数字:Valley Number,像山谷一样的数字.当一个数字,从左到右依次看过去数字没有出现先递增接着递减的"山峰"现象,就被称作 Valley Number.它可以递增,也可以递减,还可以先递减再递增.在递增或递减的过程中可以出现相等的情况.比如,1,10,12,212,32122都是 Valley Number.121,12331,21212则不是.度度熊想知道不大于N的Valley Nu

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

Valley Numer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 311    Accepted Submission(s): 165 Problem Description 众所周知,度度熊非常喜欢数字. 它最近发明了一种新的数字:Valley Number,像山谷一样的数字. 当一个数字,从左到右依次看过去数字没有出现先递增接

hdu 3555 Bomb(数位dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555 题目大意:就是给你一个数n,判断从0到n有多少个数含有数字49...... 是不是觉得跟hdu2089很相似呀... 思路:跟hdu2089一样的,注意给出的数比较大,所以这儿用__int64  .... code: #include<cstdio> #include<iostream> #include<cstring> #include<algorithm&

[ACM] hdu 2089 不要62(数位Dp)

不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 19043    Accepted Submission(s): 6442 Problem Description 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer). 杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就

HDU 2089 不要62(数位DP,三种姿势)

HDU 2089 不要62(数位DP,三种姿势) ACM 题目地址:HDU 2089 题意: 中文题意,不解释. 分析: 100w的数据,暴力打表能过 先初始化dp数组,表示前i位的三种情况,再进行推算 直接dfs,一遍搜一变记录,可能有不饥渴的全部算和饥渴的部分算情况,记录只能记录全部算(推荐看∑大的详细题解Orz) 代码: 1. 暴力 (以前写的) /* * Author: illuz <iilluzen[at]gmail.com> * File: 2089_bf.cpp * Create

HDU - 3555 Bomb (数位DP)

题意:求1-n里有多少人包含"49"的数字 思路:数位DP,分三种情况:到第i位没有49的情况,到第i位没有49且最高位是9的情况,到第i位有49的情况,将三种情况都考虑进去就是了 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; long long dp[30][3], n; int arr

HDU 4518 ac自动机+数位dp

吉哥系列故事--最终数 Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 304    Accepted Submission(s): 102 Problem Description 在2012年腾讯编程马拉松比赛中,吉哥解决了一道关于斐波那契的题目,这让他非常高兴,也更加燃起了它对数学特别是斐波那契数的热爱.现在,它又在思考一个关于斐波那契

HDU Word Index (数位DP)

题意:给你字符串,算出它的数值: a -> 1 b -> 2 . . z -> 26 ab -> 27 ac -> 28 . . az -> 51 bc -> 52 . . vwxyz -> 83681 字母要求递增. #include<cstdio> #include<stdlib.h> #include<string.h> #include<string> #include<map> #incl

HDU 4722 Good Numbers (数位dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4722 思路:数位dp,dp[i][j]表示到第i位,数字和%10为j,然后进行dp,注意完全匹配的情况是要+1,而其他情况是从0 到 9 都要考虑 代码: #include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> using namespace std; int