今天做oa遇到的一道dp,不知道为什么最后的几个testcase没有过,可能是大数溢出的问题。
为什么需要取模?
在Java中,Integer的取值范围是-2^31 to 2^31 - 1,超过此数据范围的就会整型溢出。
选择存放答案的模可以有效避免溢出。mod有以下要求:
1. mod应足够大, 以适应整数类型
2.mod应是一个质数。
因此,较多题目选择10^9 + 7 作为mod。
题目:
Input: "abcdba"
Output: 2 ("abcba", "abdba")
public int palindromeSubsequenceLenOfFive(String s){
int mod = 1000000007;
int res = 0;
int len = s.length();
//dp[i][j]: 在[i...j]中长度为3的回文子串个数
int[][] dp = new int[len][len];
//统计len = 3的回文子串,并填表
for(int i = len - 2; i >= 0; i--){
for(int j = i + 2; j < len; j++){
//减去重复统计的部分
dp[i][j] = dp[i][j - 1] + dp[i + 1][j] - dp[i + 1][j - 1];
//如果首位相同,还需要加上首位两个和中间任意一个字母组成的len =3回文子串
if(s.charAt(i) == s.charAt(j)){
dp[i][j] += j - i - 1;
}
}
}
//统计len = 5的回文串:固定首尾相同,累加中间len = 3的回文串的个数
for(int i = 0; i < len; i++){
for(int j = i + 4; j < len; j++){
if(s.charAt(i) == s.charAt(j)){
res += (dp[i + 1][j - 1]) % mod;
}
}
}
return res % mod;
}