P9232 [蓝桥杯 2023 省 A] 更小的数
暴力
直接暴力枚举区间,并且逐个判断
#include <iostream> #include <stdio.h> #include <algorithm> #include <string.h> #include <string> #include <cmath> #define R(x) x = read() #define For(i, j, n) for(int i = j ; i <= n ; ++i) using namespace std; inline int read() { int x = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } const int N = 5005; char s[N]; bool check(int l, int r) { int i = l, j = r; while(i < j) if(s[i] == s[j]) { i++; j--; } else return s[j] < s[i]; return 0; } int solve() { int res = 0; int Len = strlen(s); for(int l = 0; l < Len - 1; l++) for(int r = l + 1; r < Len; r++) if(check(l, r)) res++; return res; } int main() { scanf("%s", s); printf("%d\n", solve()); return 0; }
期望复杂度O(n^3),但是因为这道题数据比较水,check函数退出的时间比较早,这种做法居然过了。
区间DP
一开始看到5000级别的数据范围,就直接定势思维地放弃了区间DP的想法。
因为传统的区间DP需要枚举断点,时间复杂度是O(n^3)
但是这道题比较特殊,它不需要枚举断点,只要整个区间处理即可。
大佬题解:
P9232 [蓝桥杯 2023 省 A] 更小的数 - 洛谷专栏 (luogu.com.cn)
代码:
#include<bits/stdc++.h> using namespace std; char s[5010];int dp[5010][5010]; int main(){ scanf("%s",s);int n=strlen(s),ans=0; for(int i=0;i<n;i++) dp[i][i]=0; for(int i=0;i<n-1;i++) dp[i][i+1]=(s[i]>s[i+1]);//初始值 for(int len=3;len<=n;len++){ for(int i=0;i<n-len+1;i++){ int j=i+len-1; if(s[i]==s[j]) dp[i][j]=dp[i+1][j-1]; else if(s[i]>s[j]) dp[i][j]=1; } } for(int i=0;i<n;i++) for(int j=i;j<n;j++) ans+=dp[i][j];//求总数 printf("%d",ans); return 0; }