リニア思考DP + 60 CのOX-オフ練習試合のタイトル業績ハイライト

業績ハイライト

タイトル説明

そこ動きは、我々は、B、C、D、使用する各操作、離れて26種類の操作からである ...、X、Y、Z の代わりにシンボルが。
今の長さの牛肉の動作シーケンスがあるnは、彼ができるようになりました特定の操作裏返しがビデオ操作に結合することから、例えば、動作シーケンスは、ビデオの動作は、B、C、Dがあります、たとえばABCDABCDある AB、AC、広告、等(サブシーケンスの即ち動作)。彼は長さkとどのように多くの操作ビデオの異なる性質を疑問に思いました。
例えば、ABABのために、2つの異なる長さと結果の性質がAB、AA、BA、BBを持っています。
答えは非常に大きくなる可能性を考慮に入れて、あなただけの1E9 + 7意義ダイ答えそれで出力する必要があります。

説明を入力します。

最初の二つの整数のラインN、K.
長さnの列の2行目は、小文字の存在を確実にします。

出力説明:

これは、ラインの長さは、整数kおよびビデオの操作の異なる自然数であることを示します。


使用には自明のDP数列を、祈る、と明らかにDP方程式を発売することができます:

DP [I] [J] = DP [I-1] [J-1] + DP [I-1]〜[J]。

問題はどのように再実行するには、繰り返しがあるということですか?

あなたは、各文字の最後に現れる位置を記録することができ、そしてこの式は同様の接頭辞であるので、現在の手紙を減算することにより、位置の最終値は、行の前に表示されます。

DP [I]、[J] - = DP [プレ[S [i]が ' - '] - 1] [J-1]。

これは、ゼロの長さから、ここで注目されます。

コード:

#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=100010;
const int M=2000100;
const LL mod=1e9+7;
LL dp[1100][1100];
char s[1100];
int pre[30];
int main(){
	int n,k;
	cin>>n>>k;
	scanf("%s",s+1);
	dp[0][0]=1;
	for(int i=1;i<=n;i++){//位置 
		for(int j=0;j<=i;j++){//长度 
			dp[i][j]=dp[i-1][j-1]+dp[i-1][j];
			if(pre[s[i]-'a']) dp[i][j]-=dp[pre[s[i]-'a']-1][j-1];
			dp[i][j]%=mod;
		}
		pre[s[i]-'a']=i;
	}
	if(k==0){
		cout<<1<<endl;
		return 0;
	}
	if(dp[n][k]<0) dp[n][k]+=mod;
	cout<<dp[n][k]<<endl;
	return 0;
}
公開された264元の記事 ウォン称賛46 ビュー10000 +

おすすめ

転載: blog.csdn.net/qq_44291254/article/details/105161258