2019.5.1 DP专题训练 山峰数(hill)

 

 

 

 

数位dp,感觉理解更深刻了一些

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+7;
const int N=505;
ll dp[N][N][2][2];//定义状态dp[长度][前一位][是否压上界][上升还是下降]
int a[maxn];
int len;
ll dfs(int lennow,int pre,int limit,int down){
    if(lennow==len+1) return 1;
    if(dp[lennow][pre][limit][down]!=-1) return dp[lennow][pre][limit][down];//记忆化搜索的模板 
    ll ans=0;
    int maxx=limit?a[lennow]:9;//能够枚举的数,达到上限是前一个,否则就从0-9枚举 
    for(int i=0;i<=maxx;i++){
        if(!down){//如果没有下降 
            if(i>=pre){//当前的数比前一个大 ,没有在下降 
                ans+=dfs(lennow+1,i,limit && i==maxx,0);
            }
            else{
                ans+=dfs(lennow+1,i,limit && i==maxx,1);//已经在下降了,标记 
            }
        }
        else if(i<=pre){
            ans+=dfs(lennow+1,i,limit && i==maxx,1);//一直在下降 
        }    
    }
    return dp[lennow][pre][limit][down]=ans;
} 
int T;
char s[maxn];
int main()
{
    freopen("hill.in","r",stdin);
    freopen("hill.out","w",stdout);
    scanf("%d",&T);
    while(T--){
         scanf("%s",s);
         len=strlen(s);
//         printf("%d\n",len);
         for(int i=0;i<len;++i){
             a[i+1]=s[i]-'0';
        } 
//        for(int i=1;i<=len;++i){
//            printf("%d ",a[i]);
//        } 
//        printf("\n");
        bool down=false;
        bool hill=true;
        for(int i=2;i<=len;++i){//判断是否为山峰数
            if(a[i]<a[i-1])    down=true;
            if(down&&a[i]>a[i-1]){
                printf("-1\n");
                hill=false;
                break;
            }
        }
        if(hill)
        {
            memset(dp,-1,sizeof(dp));
            cout<<dfs(1,0,1,0)-1<<endl;
        }
    }
    return 0; 
} 

 

转载于:https://www.cnblogs.com/LJB666/p/10846867.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值