EOJ Monthly 2018.12-C. 她的名字

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/C_13579/article/details/84932490

地址:https://acm.ecnu.edu.cn/contest/125/problem/C/

思路:组合数学+预处理,对于以XY结尾的字符串,可以枚举所有XY为s[i]s[j],而对于s[i]s[j]的长度为k的字符串个数为 C(i,k),因此可以先预处理出所有N XY的答案,先求出C(i,j)的值d[i][j],在枚举XY,X=s[i]时,又需要求长度为1->i 的字符串个数,因此可以先保存不同XY的个数,在集中处理。

Code:

#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL; 

const int MAX_N=2e3+5;
const LL MOD=1e9+7;
int n,Q;
string s;
LL d[MAX_N][MAX_N];
LL res[MAX_N][105],dd[105];

int main()
{
	ios::sync_with_stdio(false);
	cin>>s;
	n=s.length();
	d[0][0]=1;
	for(int i=1;i<=n;++i)
	{
		d[i][0]=1;
		for(int j=1;j<=i;++j)
			d[i][j]=(d[i-1][j]+d[i-1][j-1])%MOD;
	}
	int t;
	for(int i=0;i<n-1;++i)
	{
		memset(dd,0,sizeof(dd));
		for(int j=i+1;j<n;++j)
		{
			t=(s[i]-'0')*10+s[j]-'0';
			++dd[t];
		}
		for(int j=0;j<=i;++j)
			for(int k=0;k<=99;++k)
				res[j+2][k]=(res[j+2][k]+d[i][j]*dd[k]%MOD)%MOD;
	}
	cin>>Q;
	int l;
	while(Q--){
		cin>>l>>t;
		if(l>n)	cout<<0<<endl;
		else	cout<<res[l][t]<<endl;
	}
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/C_13579/article/details/84932490