HDU6148

来源:互联网 发布:openwrt手机网络共享 编辑:程序博客网 时间:2024/06/05 08:27
简单的数位DP。只需要判断是否在递减之前出现过递增
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#include<iostream>#include<algorithm>#include<stack>#include<queue>#include<vector>#include<set>#include<map>#include<string>#define nl n<<1#define nr (n<<1)|1using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int,int>P;const int INF=0x3f3f3f3f;const ll INFF=0x3f3f3f3f3f3f3f3f;const double pi=acos(-1.0);const double eps=1e-9;const ll mod=1e9+7;int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0' | ch>'9') {if(ch=='-') f=-1;ch=getchar();}    while(ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}    return x*f;}void Out(int aa){    if(aa>9)        Out(aa/10);    putchar(aa%10+'0');}long long dp[105][105][10][2][2];int s[105];char str[105];ll rec(int i,int pre,int up,int down,int flag,int q,int len){    if(i<0)        return 1;    if(dp[i][len][pre][up][down]!=-1&&!flag&&!q)        return dp[i][len][pre][up][down];    ll res=0;    int o=s[i];    for(int j=0; j<10; j++)    {        if(j>o&&flag)            break;        if(q)            res+=rec(i-1,j,0,0,j<o?0:flag,q&&j==0,len-(q&&j==0)),res%=mod;        else if(j==pre)        {            res+=rec(i-1,j,up,down,j<o?0:flag,q&&j==0,len),res%=mod;        }        else if(j>pre)        {            res+=rec(i-1,j,1,down,j<o?0:flag,q&&j==0,len),res%=mod;        }        else if(j<pre)        {            if(up)                continue;            res+=rec(i-1,j,up,1,j<o?0:flag,q&&j==0,len),res%=mod;        }    }    if(!flag&&!q)        dp[i][len][pre][up][down]=res;    return res;}long long cal(){    int len=strlen(str);    for(int i=0; i<len; i++)    {        s[i]=str[len-1-i]-'0';        //printf("%d\n",s[i]);    }    return rec(len-1,0,0,0,1,1,len);}int main(){    memset(dp,-1,sizeof(dp));    int t;    scanf("%d",&t);    while(t--)    {        scanf("%s",str);        printf("%I64d\n",(cal()-1+mod)%mod);    }    return 0;}

原创粉丝点击