列表

详情


NC204019. 操作集锦

描述

有一款自走棋有26种操作,每种操作我们都用的符号来代替. 
现在牛牛有一个长度为的操作序列,他现在可以从里面拿出某些操作来组合成一个操作视频, 比如说操作序列是,那么操作视频就有等(也就是操作序列的子序列).他现在想知道长度为且本质不同的操作视频有多少种.
比如对于,长度为且本质不同的结果有
考虑到答案可能非常大,你只需要输出在模意义下的答案就可以了.

输入描述

第一行两个整数.
第二行一个长度为的字符串,保证只存在小写字母.

输出描述

一行一个整数表示长度为且本质不同的操作视频的个数. 

示例1

输入:

3 1
abc

输出:

3

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 9ms, 内存消耗: 7268K, 提交时间: 2020-03-28 23:42:36

#include <bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
char s[1000];
long long f[1005][1005], g[30]= {0};
int main() {
	int n, k;
	scanf("%d%d%s", &n, &k, s+1);
	for(int i=1; i<=n; i++) {
		f[i-1][0]=1;
		for(int j=1; j<=i; j++) {
			f[i][j]=(f[i-1][j]+f[i-1][j-1])%mod;
			if(g[s[i]]) f[i][j]-=f[g[s[i]]-1][j-1];
			f[i][j]=(f[i][j]+mod)%mod;
		}
		g[s[i]]=i;
	}
	f[n][0]=1;
	cout<<f[n][k]%mod<<endl;
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 12ms, 内存消耗: 8460K, 提交时间: 2020-03-28 17:39:48

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1010,mod=1e9+7;
int t,n,k; 
char s[N];
ll dp[N][N],f[N][30];
int main(){
	cin>>n>>k>>s+1;
	dp[0][0]=1;
	for(int i=1;i<=n;i++)
	{
		dp[i][0]=1;
		for(int j=1;j<=k;j++)
		{
			dp[i][j]=(dp[i-1][j]+dp[i-1][j-1]-f[j][s[i]-'a']+mod)%mod;
			f[j][s[i]-'a']=dp[i-1][j-1];
		}
	}
	ll ans=0;
	cout<<dp[n][k]; 
	return 0;
}

上一题