本题考的区间dp
先枚举长度,再枚举右端点
1.右端点大于左端点 则将$ dp[l][r] $设为1
2.右端点等于左端点,则可以看$dp[l-1][r-1]$是否为1
3.右端点小于左端点,不进行任何操作
#include<bits/stdc++.h>
using namespace std;
const int N=5e3+10;
int n,dp[N][N],res;
int main(){
string s;
cin>>s;
n=s.size();
for(int len=2;len<=n;++len){
for(int l=0;l+len-1<n;++l){
int r=l+len-1;
if(s[l]>s[r])dp[l][r]=1;
else if(s[l]==s[r])dp[l][r]=dp[l+1][r-1];
res+=(dp[l][r]==1);
}
}
cout<<res<<endl;
return 0;
}
原来区间dp在这种时候用的orz
感觉可以i倒着枚举子串的首,j正着枚举子串的尾,然后每算出来一个子串是ok的,就把ok[i][j]标记为true,后面再用ok[i][j]的值更新的子串,两者思路完全一致:)
orz
or2
orz
orz
orz
orz