You are given a string which is the hint of a password. Given string only consist of character '1' to '9' and '-'.You can replace '-' by any digit from '1' to '9'.Find the number of ways to make a password by replacing all '-' characters to some digit, such that the digits of the password are in non-decreasing order.
If it is impossible to make the digits of the string in non-decreasing order, print "0" otherwise since the answer can be very large, print the answer modulo 10^9+7.
The sequence a is called non-decreasing if a1≤a2≤⋯≤an holds, where n is the length of the sequence.
Input
The first line contains an integer t (1≤t≤10^2) −− the number of test cases in the input.
Then t test cases follow.
The first line of the test case contains one integer n (1≤n≤10^5).
The second line of the test case contains a string s of n characters, consisting only '1' to '9' and '-'.
It is guaranteed that the sum of the values of n for all test cases in the input does not exceed 10^5.
Output
For each test case, If it is impossible to make the digits of the string in non-decreasing order, print "0" otherwise print the number of ways modulo 109+7
input
5
5
1---2
3
3-4
7
2--43-4
8
1---23-4
1
-
output
4
2
0
8
9
Note
In the first test, we have four ways to fill '-' characters 111, 112, 122, 222.
In the second test, we have two ways to fill the '-' character, 3 or 4.
In the third test, it is impossible to convert this into a valid string.
题意:给定长度为n的字符串,'-'可以是1~9,问构造整个序列数值不递减的方案数mod(1e9+7)。
解析:首先判断无解的情况就是原始序列中数字已经出现非递减的情况,输出0即可。
对于有解情况,我们可以单独取出每一段'-'的区间考虑,那么答案肯定就是每一段方案数相乘。对于每一段,我们可以得知取值肯定是[L,R],L是a[l]-'0',R是a[r]-'0'。
我们可以考虑dp[ i ][ j ]是长度为 i ,最后一位是数字 j 的方案数,那么对于 i j,方案数就是 dp[i-1][L~j]的总和。
#include
using namespace std;
const int N=1e5+5,mod=1e9+7;
typedef pair PII;
char a[N];
void solve()
{
int n,mx=0;//mx表示当前最大出现数字
scanf("%d%s",&n,a+1);
for(int i=1;i<=n;i++)
{
if(a[i]!='-')//数字
{
if(a[i]-'0' v;//存储每一个'-'连续区间
int l=-1,r;
a[0]='1',a[n+1]='9';//便于考虑边界情况
for(int i=1;i<=n+1;i++)
{
if(a[i]=='-'&&l==-1) l=i,r=i;
else if(a[i]=='-') r=i;
else
{
if(l!=-1) v.push_back({l,r});
l=-1;
}
}
int sum=1;
for(int i=0;i> dp;
dp.resize(len+5);
for(int j=0;j<=len;j++) dp[j].resize(15,0);
for(int j=l;j<=r;j++) dp[1][j]=1;//前i个位置最后一位是j
for(int j=1;j<=len;j++)
{
for(int k=l;k<=r;k++)
{
for(int h=l;h<=k;h++)
{
dp[j][k]=(dp[j][k]+dp[j-1][h])%mod;
}
}
}
int res=0;//当前该区间的方案数
for(int j=l;j<=r;j++) res=(res+dp[len][j])%mod;//长度为len,以[l,r]结尾的方案数
sum=sum*res%mod;//每个区间方案数相乘
}
printf("%d\n",sum);
}
int main()
{
int t=1;
scanf("%d",&t);
while(t--) solve();
return 0;
}