zoukankan      html  css  js  c++  java
  • 【hdu6148】Valley Numer【数位dp模板题】

    题意

      对于每组数据给出一个整数n(length(n)<=100),找出不大于n的数字中有多少是Valley Numer。对于Valley的定义是它每一位的数字要么是递增,要么是递减,要么是先递减后递增

    分析

      选拔赛的时候遇到了数位dp,以前只是听说但是没学过今天就拿出来一天的时间学了一下数位DP。

      我们发现单调递减变为单调递增合法,单调递增变为递减不合法,所以通过增减判断最多只有一个拐点。那么我们在dp的时候状态只要记录当前是递增还是递减就可以了。

      我们用dp[p][pre][state]来进行记忆化。p代表的是位数,pre代表的是上一位的值,state代表是递减还是递增。

      这个算是数位dp很板子的一个题目,但是我一开始一直wa,感觉自己考虑的很对,然后最后看题解发现自己没有考虑前导0.

      我们发现,当存在前导0的时候,相当于从这里新开一个数字,那么当前是递增还是递减就不确定了,没法根据前面的0来判断,所以当存在前导0的时候步可以记忆化否则会因为dp数组的冲突而导致答案错误。

      

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 
     6 using namespace std;
     7 typedef long long LL;
     8 const int mod=1000000007;
     9 const int maxn=100+10;
    10 int n,a[maxn],pos,T;
    11 char s[maxn];
    12 LL dp[maxn][10][2];//0 上升 1 下降
    13 LL dfs(int p,int pre,int state,int lead,int limit){
    14     if(p==0){
    15         if(lead)
    16             return 0;
    17         return 1;
    18     }
    19     if(!limit&&dp[p][pre][state]!=-1&&!lead)
    20         return dp[p][pre][state];
    21     int up=limit?a[p]:9;
    22     LL res=0;
    23     for(int i=up;i>=0;i--){
    24         if(state==0&&i<pre)
    25             continue;
    26         int st;
    27         if(i==pre)st=state;
    28         else if(i<pre)st=1;
    29         else st=0;
    30         if(lead)st=1;
    31         res=(res+dfs(p-1,i,st,lead&&i==0,limit&&i==a[p]))%mod;
    32     }
    33     if(!limit&&!lead)
    34         dp[p][pre][state]=res;
    35     return res;
    36 }
    37 LL solve(){
    38     pos=0;
    39     for(int i=n-1;i>=0;i--){
    40         pos++;
    41         a[pos]=s[i]-'0';
    42     }
    43     memset(dp,-1,sizeof(dp));
    44     return dfs(pos,0,0,1,1);
    45 }
    46 int main(){
    47     scanf("%d",&T);
    48     for(int t=1;t<=T;t++){
    49         scanf("%s",s);
    50         n=strlen(s);
    51         printf("%lld
    ",solve()%mod);
    52     }
    53 return 0;
    54 }
    View Code
  • 相关阅读:
    C++实现二叉树的相应操作
    C++对文件的操作
    C++与C的区别二
    C++多线程编程二
    C++多线程编程一
    C语言多线程编程二
    C语言多线程编程一
    HTML练习(三)
    磁盘/内存模式查询数据
    RestTemplate使用不当引发的问题分析
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/9649713.html
Copyright © 2011-2022 走看看