1. 程式人生 > >HackerRank Week of Code -18 GG

HackerRank Week of Code -18 GG

The only permutation that satisfies the given pattern is (2,1,0).

 題目大意:

    給出陣列中相鄰間的大小關係,求有多少種排列滿足給出的要求。

解題思路:

       由資料範圍知應該是n^2演算法,就想到了DP,dp[i][j],i表示第i位,j表示有多少個比當前這個數小。如果i位比i+1位大,下一步有可能dp[i+1][j]就可以從所有的dp[i][k>j]的,同理第i位比i+1小的也一樣,於是可以用2個字首和處理一下。

程式碼:

#include<iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=3000+10;
int dp[maxn][maxn];
char s[maxn];
int a[maxn];
int b[maxn];
int main()
{
	int n,m;
	while(~scanf("%d%d",&n,&m))
	{
		memset(dp,0,sizeof(dp));
		scanf("%s",s);
		int ans=0;
		for(int i=0;i<n;i++)
			dp[1][i]=1;
		for(int i=1;i<n;i++)
		{
			memset(a,0,sizeof(a));
			a[0]=dp[i][0];
			for(int j=1;j<n;j++)
				a[j]=(a[j-1]+dp[i][j])%m;
			b[n-1]=dp[i][n-1];
			for(int j=n-2;j>=0;j--)
				b[j]=(dp[i][j]+b[j+1])%m;
			for(int j=0;j<n;j++)
			{
				if(s[i-1]=='G')
				{
					if(b[j+1])
						dp[i+1][j]=(dp[i+1][j]+b[j+1])%m;
				}
				else
				{  
					if(i+1+j<=n)
					dp[i+1][j]=(dp[i+1][j]+a[j])%m;
 				}
			}
		}
		cout<<dp[n][0]<<endl;
	}
	return 0;
}