思路1暴力
找到前面大于后面就反转,相等就向内部找
#include<bits/stdc++.h>
using namespace std;
const int N = 5005;
int a[N];
int main(){
string n;
cin >> n;
int s = n.size();
int cnt = 0;
for(int i = 0; i < s; i ++ ) a[i] = n[i] - '0';
for(int i = 0; i < s - 1; i ++ ) {
for(int j = i + 1; j < s; j ++ ) {
int l = i, r = j;
while(a[r] == a[l] && r > l ) {
r --, l ++;
}
if(a[l] > a[r] && r > l ) {
cnt ++ ;
}
}
}
cout << cnt;
return 0;
}
注意l--,r++有可能跳过l=r直接l>r所以不能用l!=r判断
但是三重循环TLE了~~
思路2优化之后的暴力
从内向外找
注意:数组越界、双指针交错,while循环的break
#include<bits/stdc++.h>
using namespace std;
const int N = 5005;
int a[N];
int main(){
string n;
cin >> n;
int s = n.size();
int cnt = 0;
for(int i = 0; i < s; i ++ ) a[i] = n[i] - '0';
for(int i = 0; i < s - 1; i ++ ) {
for(int j = i + 1; j < s; j ++ ) {
int l = i, r = j;
if(a[r] < a[l] && r > l) {
cnt ++;
l --, r ++;
while(a[r] == a[l] && l >= 0 && r < s){
cnt ++;
l --, r ++;
}
}
}
}
cout << cnt;
return 0;
}
可见有时候调整一下暴力的思路就可以AC
思路三区间DP
用二维数组存储了比较过的结果,用空间换时间
#include<bits/stdc++.h>
using namespace std;
const int N=5e3+10;
int n,dp[N][N],res;
//用dp标记这个序列是否符合条件,用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;
}