题意:给字符串,问删掉0个及以上的字符让字符串变成回文串(字符串不能为空)方法数
#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
const int N=2005;
typedef long long LL;
LL dp[N][N];//dp[i][j]为删除[i,j]个字符的方法数量
int main(){
int t;scanf("%d",&t); //T个样例
while(t--){ //自减
char str[N];scanf("%s",str);//输入串
int len=strlen(str); //得长度
memset(dp,0,sizeof(dp));//DP清空
for(int i=0;i<len;i++)dp[i][i]=1;//全部初始化为1
for(int i=len-1; i>=0; i--)//I从右界开始往左移
for(int j=i+1; j<len; j++){//J从I+1开始扫到右界
if(str[i]==str[j])//但是如果当前左右界的字符是相等的
dp[i][j]=(dp[i+1][j]+dp[i][j-1])%mod;//解释见文末
else//但是如果当前左右界的字符是不等的,则左右界的字符必须删除
dp[i][j]=(dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1]+mod)%mod;//解释见文末
}
printf("%lld\n",dp[0][len-1]);//输出0到LEN-1区间的DP值就是结果
/*打一个表看很明显
cout<<" 0 1 2 3"<<endl;
for(int i=0;i<len;i++){
cout<<i<<' ';
for(int j=0;j<len;j++){
cout<<dp[i][j]<<' ';
}
cout<<endl;
}
1
abcd
4
0 1 2 3
0 1 2 3 4
1 0 1 2 3
2 0 0 1 2
3 0 0 0 1
右上角每个更新的值都是左+下-左下*/
}
return 0;
}
Sample Input 1
6
bob
a
aa
aaa
abcdb
kaia
Sample Output 1
5
1
3
7
8
6
note: kaia的6种方法
删0个字符:0种
删1个字符:1种,删K
删2个字符:1种:删KI
删3个字符:4种,C(4,3)任选
不能删四个字符(不能变空串),当然,如果题目允许空的话,答案再+1即可