Leetcode第 368 场周赛

元素和最小的山形三元组 II

预处理前缀和后缀最小值,记为pre[i]和sa[i]

对于当前编号i,如果前面的最小值和后面的最大值都小于nums[i],则记录ans[i] = nums[i]+pre[i-1]+sa[i+1]

结果输出最小的ans[i]即可。

合法分组的最少组数

统计每一个数字出现的次数。将每一个数字分为大小为 d d d或 d + 1 d+1 d+1的组,令 d d d尽可能大。
d d d不满足单调性,不好二分。思路时直接暴力。

计最小出现次数为 m n mn mn,出现过的数字个数为 c n t cnt cnt,显然有 m n ∗ c n t ≤ n u m s . l e n g t h mn*cnt \le nums.length mn∗cnt≤nums.length

而显然有 d + 1 ≤ m n d+1 \le mn d+1≤mn,因此直接枚举d

对于某个数字i,其出现次数为 t o t i tot_i toti,若 d d d成立则需要满足存在x令 x d ≤ t o t i ≤ x ( d + 1 ) xd \le tot_i \le x(d+1) xd≤toti≤x(d+1)

令 x = t o t i / d x = tot_i/d x=toti/d,即以 d d d为标准将 t o t i tot_i toti分为x组,此时还剩 t o t i % d tot_i\%d toti%d个元素,每一组中最多可以容纳 d + 1 d+1 d+1个元素,最多可以容纳x个元素,使x组的个数都变为%d+1%。因此只要满足 t o t i % d ≤ x tot_i\%d \le x toti%d≤x即 t o t i % d ≤ t o t i / d tot_i\%d \le tot_i/d toti%d≤toti/d,则对数字 i i i而言 d d d是合法的分组。

已知d,数字i的分组个数为 t o t i + d m n + 1 \frac{tot_i+d}{mn+1} mn+1toti+d。 x x x需要取最小值满足 x d ≤ t o t i ≤ x ( d + 1 ) xd \le tot_i \le x(d+1) xd≤toti≤x(d+1),有 ⌈ t o t i / ( d + 1 ) ⌉ ≤ x \lceil tot_i/(d+1)\rceil \le x ⌈toti/(d+1)⌉≤x,因此取 x = ⌈ t o t i d + 1 ⌉ x =\lceil \frac{tot_i}{d+1}\rceil x=⌈d+1toti⌉

枚举 d d d,计算分组个数,求分组最小值即可,复杂度为 O ( m n ∗ c n t ) O(mn*cnt) O(mn∗cnt)

得到 K 个半回文串的最少修改次数

数据只有200,想法是纯暴力

令 M i n T i m e s [ i ] [ j ] MinTimes[i][j] MinTimes[i][j]为子串 s t r i j str_{ij} strij变成半回文串最少的次数,暴力计算,复杂度为 O ( n 4 ) O(n^4) O(n4)

令dp[i][j]为以 s t r i str_i stri为结尾时分为 j j j段最少的操作次数
d p [ i ] [ j ] = min ⁡ d p [ z ] [ j − 1 ] + M i n T i m e s [ z + 1 ] [ i ] dp[i][j] = \min dp[z][j-1]+MinTimes[z+1][i] dp[i][j]=mindp[z][j−1]+MinTimes[z+1][i]

总复杂度 O ( n 4 ) O(n^4) O(n4)

计算MinTimes时可以将一个n优化成 n \sqrt n n 甚至预处理成 lg ⁡ n \lg n lgn,但是 O ( n 4 ) O(n^4) O(n4)也能过就是了,大概是数据比较弱吧

cpp 复制代码
class Solution {
public:
    int MinTimes[210][210];
    int dp[210][210];
    int calTimes(string &s,int l,int r)
    {
        int ret = (1<<30);
        int len = r-l+1;
        while(--len)
        {
            if((r-l+1)%len)
                continue;
            int ans = 0;
            for(int i=0;i<len;++i)
            {
                string t1;
                for(int j=l+i;j<=r;j+=len)
                    t1 += s[j];
                for(int c=0;c<t1.size()/2;++c)
                    if(t1[c]!=t1[t1.size()-1-c])
                        ans++;
            }
            ret = min(ret,ans);
        }
        return ret;
    }
    int minimumChanges(string s, int k) {
        memset(dp,0x3f,sizeof(dp));
        dp[0][0] = 0;
        int l = s.size();     
        for(int i=0;i<l;++i)
        {
            for(int j=i+1;j<l;++j)
            {
                MinTimes[i][j] = calTimes(s,i,j);
            }
            MinTimes[i][i] = (1<<30);
        }
        for(int i=0;i<l;++i)
        {
            for(int j=0;j<=i;++j)
            {
                for(int z=1;z<=k;++z)
                {
                    dp[i+1][z] = min(dp[i+1][z],dp[j][z-1]+MinTimes[j][i]);
                }
            }
        }
        return dp[l][k];
    }
};
相关推荐
董董灿是个攻城狮3 小时前
5分钟搞懂什么是窗口注意力?
算法
Dann Hiroaki4 小时前
笔记分享: 哈尔滨工业大学CS31002编译原理——02. 语法分析
笔记·算法
qqxhb5 小时前
零基础数据结构与算法——第四章:基础算法-排序(上)
java·数据结构·算法·冒泡·插入·选择
FirstFrost --sy7 小时前
数据结构之二叉树
c语言·数据结构·c++·算法·链表·深度优先·广度优先
森焱森7 小时前
垂起固定翼无人机介绍
c语言·单片机·算法·架构·无人机
搂鱼1145147 小时前
(倍增)洛谷 P1613 跑路/P4155 国旗计划
算法
Yingye Zhu(HPXXZYY)7 小时前
Codeforces 2021 C Those Who Are With Us
数据结构·c++·算法
独行soc8 小时前
2025年渗透测试面试题总结-2025年HW(护网面试) 33(题目+回答)
linux·科技·安全·网络安全·面试·职场和发展·护网
无聊的小坏坏9 小时前
三种方法详解最长回文子串问题
c++·算法·回文串
长路 ㅤ   9 小时前
Java后端技术博客汇总文档
分布式·算法·技术分享·编程学习·java后端