标签:
题意:
给长度为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