题意:
给长度为N的字符串,只存在小写字母。
问你山形的子序列有多少种,这里是子序列不是子串。
所谓的山形就是严格的递增到递减。
思路:
dp[i][j][k]代表前i个字母,前面的字母是j的k状态有多少种。
状态0为什么都没,1为上山,2为下山,3为答案状态。
滚动数组维护就好了。
代码:
#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
#include"map"
#include"vector"
#define ll long long
using namespace std;
char v[123456];
int dp[2][28][5];
int main()
{
int n;
while(scanf("%d",&n)!=-1)
{
memset(dp,0,sizeof(dp));
scanf("%s",v+1);
dp[0][0][0]=1;
for(int i=1; i<=n; i++)
{
for(int j=0; j<=26; j++) for(int k=0; k<4; k++) dp[i%2][j][k]=dp[1-i%2][j][k];
for(int j=0; j<=26; j++)
{
int tep=v[i]-'a'+1;
if(tep>j)
{
dp[i%2][tep][1]=(dp[i%2][tep][1]+dp[1-i%2][j][1]+dp[1-i%2][j][0])%2012;
dp[i%2][tep][2]=(dp[i%2][tep][2]+dp[1-i%2][j][1])%2012;
}
else if(tep<j)
{
dp[i%2][tep][2]=(dp[i%2][tep][2]+dp[1-i%2][j][2])%2012;
dp[i%2][tep][3]=(dp[i%2][tep][3]+dp[1-i%2][j][2])%2012;
}
}
}
int ans=0;
for(int i=0; i<=26; i++) ans=(ans+dp[n%2][i][3])%2012;
printf("%d\n",ans);
}
return 0;
}
[dp] upcpj 2221 Mountain Subsequences
原文:http://blog.csdn.net/wdcjdtc/article/details/45037871