HDU 6148 Valley Numer

标签(空格分隔): 数位DP


题目链接
开始递增后就不能递减了

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long ll;
ll read()
{
	ll 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;
}
const int mod=1e9+7;
int T,n[105],f[105][11][2];char s[105];
void MOD(int &x,int y)
{
	x+=y;
	if(x>=mod)x-=mod;
}
int dp(int step,int last,int k,int lim)
{
	if(step==0)return 1;
	if(!lim&&~f[step][last][k])return f[step][last][k];
	int x=lim?n[step]:9,res=0;
	for(int i=0;i<=x;i++)
	{
		if(k&&i<last)continue;
		int nt=(i==0&&last==10?10:i);
		MOD(res,dp(step-1,nt,k||(i>last&&last!=10),lim&&i==x));
	}
	if(!lim)f[step][last][k]=res;
	return res;
}
int main()
{
	memset(f,-1,sizeof(f));
	T=read();
	for(int kase=1;kase<=T;kase++)
	{
		scanf("%s",s+1);
		int len=strlen(s+1);
		for(int i=1;i<=len;i++)n[i]=s[len-i+1]-'0';
		int ans=0;
		for(int i=0;i<=n[len];i++)MOD(ans,dp(len-1,i==0?10:i,0,i==n[len]));
		printf("%d\n",((ans-1)%mod+mod)%mod);
	}
	return 0;
}

posted @ 2018-05-10 11:43  LJZ_C  阅读(80)  评论(0编辑  收藏  举报