4632
?這是一道區間dp的題目;
題意:就是給你一個字符串,讓你找出回文子序列(可以不連續)的總數。
之前在Noj上的一道 【回文字符串】也可以用這種方法。
如果str[i]=str[j] ? ? dp[i][j]=dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1]+1;
?else ? dp[i][j]=dp[i+1][j]+dp[i][j-1];
dp[i][j]代表的是從i到ji段的字符串存在多少的回文子序列。但是要注意終點的時候如果你固定左邊開始的話,那你要先知道右邊的dp值,這樣會很煩的。所以還是控制右邊來向左邊來找吧。(你可以假設一下,你第一次就直接去從找dp【0】【len-1】那你就必須找到前面的dp值,這樣你可以用深深搜l寫,但是這樣時間會比較的長,會超時。
所以你可以試著用遞推來寫,這樣你就需要控制那個方向的位置。
用遞推來寫#include <math.h>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int xx= 1e3+60;
int dp[xx][xx];
char str[xx];
const int mod=10007;int main()
{int T,CASE=0;scanf("%d", &T);while(T--){scanf("%s", str);int len =strlen(str);memset(dp,0,sizeof(dp));for(int i =0; i<len;i++)dp[i][i]=1;for(int i=0; i<len;i++)for(int j=i-1;j>=0;j--){dp[j][i]=dp[j+1][i]+dp[j][i-1];if(str[j]==str[i]) dp[j][i]++;elsedp[j][i]-=dp[j+1][i-1];dp[j][i]=(dp[j][i]+mod)%mod; //此處注意,10008%10007=1,但10006%10007=10006,所以此處的可以使負數}printf("Case %d: %d\n",++CASE,dp[0][len-1]);}return 0;
}
總結
- 上一篇: 2013 多校联合4 1011 Flip
- 下一篇: 每日阅读(产品) 汤道QQ与微信