hdu 6148 数位dp

来源:互联网 发布:怎么复制淘宝上的图片 编辑:程序博客网 时间:2024/05/15 23:45

题意:中文题,求小于等于n的"山谷"数的个数

思路:数位dp,注意此题中状态转移与前导0有关即可。

代码:

#include<bits/stdc++.h>using namespace std;#define MEM(a,b) memset(a,b,sizeof(a))#define bug puts("bug");#define PB push_back#define MP make_pair#define X first#define Y secondtypedef unsigned long long ll;typedef pair<int,int> pii;const int maxn=1e5+10;const int mod=1e9+7;using namespace std;ll f[200][20][2];int len,a[105];string str;ll dfs(int p,int nu,int isup,int lim,int lead){    if(p==str.size())return 1;    if(!lead&&!lim&&f[p][nu][isup]!=-1)return f[p][nu][isup];    ll ans=0;    int up=lim?a[p]:9;    for(int i=0;i<=up;i++){        if(isup==0){            if(i<=nu)ans=(ans+dfs(p+1,(lead&&i==0)?9:i,0,lim&&i==a[p],lead&&i==0))%mod;            else ans=(ans+dfs(p+1,i,1,lim&&i==a[p],lead&&i==0))%mod;        }        else if(isup==1&&i>=nu)ans=(ans+dfs(p+1,i,1,lim&&i==a[p],lead&&i==0))%mod;    }    if(!lim&&!lead) return f[p][nu][isup]=ans%mod;    return ans%mod;}int main(){    int t;    scanf("%d",&t);    while(t--){        cin>>str;        for(int i=0;i<str.size();i++)a[i]=str[i]-'0';        memset(f,-1,sizeof(f));        ll ret=(dfs(0,9,0,1,1)-1LL+mod)%mod;        cout<<ret<<endl;    }    return 0;}


原创粉丝点击