链接:https://ac.nowcoder.com/acm/contest/885/G
来源:牛客网
题目描述
You are given two strings s and t composed by digits (characters ‘0’ \sim∼ ‘9’). The length of s is n and the length of t is m. The first character of both s and t aren’t ‘0’.
Please calculate the number of valid subsequences of s that are larger than t if viewed as positive integers. A subsequence is valid if and only if its first character is not ‘0’.
Two subsequences are different if they are composed of different locations in the original string. For example, string “1223” has 2 different subsequences “23”.
Because the answer may be huge, please output the answer modulo 998244353.
输入描述:
The first line contains one integer T, indicating that there are T tests.
Each test consists of 3 lines.
The first line of each test contains two integers n and m, denoting the length of strings s and t.
The second line of each test contains the string s.
The third line of each test contains the string t.
-
1 \le m \le n \le 30001≤m≤n≤3000.
-
sum of n in all tests \le 3000≤3000.
-
the first character of both s and t aren’t ‘0’.
输出描述:
For each test, output one integer in a line representing the answer modulo 998244353.
示例1
输入
复制
3
4 2
1234
13
4 2
1034
13
4 1
1111
2
输出
复制
9
6
11
说明
For the last test, there are 6 subsequences “11”, 4 subsequcnes “111” and 1 subsequence “1111” that are valid, so the answer is 11.
当时在写B题的时候队友就把这个题讨论完了。。结束之后又看了看,觉得挺好的一个题目。分两种情况,一种是和下面的字符串长度相等的时候,另一种是长于下面字符串的时候。第一种时候我们可以直接写出来,但是第二种的时候,我们就需要讨论了,因为有时候在某一位的数字是一样的。。可以用dp来做,但是我们队的dp实在是不咋样。就用搜索了。一开始就是暴力搜索,T了一发之后改的记忆化搜索。还有用c++11交的时候溢出了,用c++14过得。
代码如下:
#include<stdio.h>
#include<algorithm>
#include<cstring>
using namespace std;
char s[4005];
char s1[4005];
typedef long long ll;
const ll mod=998244353;
//组合数打表模板,适用于N<=3000
//c[i][j]表示从i个中选j个的选法。
long long C[4005][4005];
void get_C()
{
C[0][0] = 1;
for(int i=1;i<=3000;i++)
{
C[i][0] = 1;
for(int j=1;j<=i;j++)
C[i][j] = (C[i-1][j]+C[i-1][j-1])%mod;
}
}
ll power(ll a,ll b)
{
ll ans=1;
ll res=a%mod;
while(b)
{
if(b&1) ans*=res,ans%=mod;
res*=res;
res%=mod;
b>>=1;
}
return ans%mod;
}
ll n,m;
ll dp[4050][4050];
inline ll check(ll pos,ll cnt)
{
ll sum=0;
if(dp[pos][cnt]!=-1) return dp[pos][cnt]%mod;
for(int i=pos;i<=n-(m-cnt);i++)
{
if(s[i]>s1[cnt])
{
sum=sum+C[n-i][m-cnt]%mod;
sum=sum%mod;
}
else if(s[i]==s1[cnt])
{
sum=sum+check(i+1,cnt+1)%mod;
sum=sum%mod;
}
}
return dp[pos][cnt]=sum%mod;
}
int main()
{
int t;
scanf("%d",&t);
get_C();
while(t--)
{
ll sum=0;
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
dp[i][j]=-1;
}
}
scanf("%s",s+1);
scanf("%s",s1+1);
ll ans=0;
for(int i=1;i<=n;i++) if(s[i]=='0') ans++;
if(ans!=0)
{
for(int i=m+1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(s[j]!='0')
{
sum=sum+C[n-j][i-1]%mod;
sum=sum%mod;
}
}
sum=sum%mod;
}
}
else
{
for(int i=m+1;i<=n;i++)
{
sum=sum+C[n][i]%mod;
sum=sum%mod;
}
}
sum=sum+check(1L,1L)%mod;
printf("%lld\n",sum%mod);
}
}
努力加油a啊,(o)/~