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;
}

 

posted @ 2024-04-08 10:51  Gold_stein  阅读(18)  评论(0编辑  收藏  举报