您的位置:首页 > 其它

hdu 6148 Valley Number 数位dp

2018-03-11 19:44 387 查看
中文题就不说题意了。。。

记录了三个状态,上一个数字是增还是减,上一个数字,前导0。前导0不合法。

inc表示增减,0表示减,1表示增。

注意相等时候应保留前一位的增长还是减少,先增加再等再下降也是属于山峰的。

#include<bits/stdc++.h>
using namespace std;

const int maxn=10;
const int mod=1e9+7;

long long dp[105][3][15];
long long num[105];

long long dfs(long long pos,int inc,int pre,int lead,int status)
{
if(pos<0)
{
return !lead;
}
if(!status&&dp[pos][inc][pre]!=-1)
return dp[pos][inc][pre];
int ans=status?num[pos]:9;
long long res=0;
for(int i=0;i<=ans;i++)
{
if(lead)
{
if(i==0)
res=(res+dfs(pos-1,2,0,1,status&&i==ans))%mod;
else
res=(res+dfs(pos-1,2,i,0,status&&i==ans))%mod;
}
else
{
if(i<pre)
{
if(inc!=1)
res=(res+dfs(pos-1,0,i,0,status&&i==ans))%mod;
}
else if(i>pre)
{
res=(res+dfs(pos-1,1,i,0,status&&i==ans))%mod;
}
else res=(res+dfs(pos-1,inc,i,0,status&&i==ans))%mod;
}
}
if(!status&&!lead)
dp[pos][inc][pre]=res;
return res;
}

int main()
{
long long n,m;
int T;
int kase=1;
cin>>T;
while(T--)
{
string s;
cin>>s;
long long res;
long long cnt=0;
n=s.length();
memset(dp,-1,sizeof(dp));
for(int i=0;i<n;i++)
num[n-1-i]=s[i]-'0';
res=dfs(n-1,0,0,1,1);
cout<<res<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息