LeetCode---117双周赛---容斥原理

news2024/11/25 4:31:17

题目列表

2928. 给小朋友们分糖果 I

2929. 给小朋友们分糖果 II

2930. 重新排列后包含指定子字符串的字符串数目

2931. 购买物品的最大开销

一、给小朋友们分糖果I

看一眼数据范围,如果没有啥其他想法思路就直接暴力,时间复杂度O(n^2)

思路:枚举前两个小朋友分得的合法糖果数,看第三个小朋友的糖果数是否符合条件

代码如下

class Solution {
public:
    int distributeCandies(int n, int limit) {
        int ans=0;
        for(int i=0;i<=min(n,limit);i++){
            for(int j=0;j<=min(n-i,limit);j++){
                ans+=(n-i-j<=limit);
            }
        }
        return ans;
    }
};

二、给小朋友们分糖果II

 

和上一题一样的题目,数据范围变大,不能暴力,需要优化时间复杂度,如何优化???

上一题思路是枚举两个元素,来看第三个元素是否符合条件,但其实我们只要枚举一个元素,就能知道剩余的糖果如何分配,才能合法,因为剩余两个元素的和是固定的

举个例子:如果剩余的糖果数为10,limit=3,分配的方式为:3和7,4和6,5和5,6和4,7和3,一共7-3+1=5种,即我们只要能算出第二个元素或第三个元素的取值范围,就能得到合法的方案数

设left为剩余糖果的数量,总共有三种情况

1.left<=limit,即剩下的糖果随便怎么分都行,共有left+1种方案,注意0和left也是一种方案

2.left>limit*2,即剩下的糖果无论怎么分,都会有一个人的糖果数>limit,方案数为0

3.limit<left<=limit*2,即有合法的分配方案,但不能随意分配,有限制,其中一个人的糖果数范围是[left-limit,limit],共有limit-(left-limit)+1种方案数

代码如下 

class Solution {
public:
    int distributeCandies(int n, int limit) {
        int ans=0;
        for(int i=0;i<=min(n,limit);i++){
            int left=n-i;
            if(left<=limit)
                ans+=left+1;
            else if(limit*2>=left){
                int x=left-limit;
                ans+=limit-x+1;
            }
        }
        return ans;
    }
};

这题还有一个O(1)时间复杂度的算法,利用容斥原理来做,不了解的可以去了解一下

这题可以转换为将n个球放入3个不同的盒子中,盒子可以为空,且每个盒子最多装limit个球,问共有多少方案?非常经典的数学题,解题思路是合法方案数 = 总的方案数 - 不合法的方案数,其中总的方案数很容易求,不合法的方案数可以用容斥原理求,两个的时间复杂度都为O(1)

1.总的方案数的求解

"隔板法" :将n个球放成一排,在他们中间插入两个隔板,将球分为三组,有多少种排列方式,注意两个隔板可以放在一起,因为题目允许盒子为空,根据排列组合,共有C(n+2,2)种方法

可能有人对这个公式的由来不理解,其实我们也可以用乘法原理来求解,我们先将一个隔板插入,有n+1个位置可以选,再将第二个隔板插入,这时第一个隔板也被看做是球,则有n+2个位置可以选,而两个隔板的放置可能出现第一个隔板的位置和上一次第二个隔板的位置相同,第二个隔板的位置和上一次第一个隔板的位置相同的情况,所以总方案数要除以2,为(n+1)*(n+2)/2=C(n+2,2)

2.不合法的方案数---容斥原理

集合A---A盒中球的数量超出limit的方案数

集合B---B盒中球的数量超出limit的方案数

集合C---C盒中球的数量超过limit的方案数

根据容斥原理:不合法的方案数=A+B+C-A∩B-A∩B-A∩B+A∩B∩C

而A=B=C,A∩B=A∩C=B∩C

所以我们只要求三个数就行

A:提前在A盒中放入limit+1个球,让剩下的球随便放,方案数为C(n-limit-1+2,2)

A∩B:提前在A盒、B盒中放入limit+1个球,让剩下的球随便放,方案数为C(n-2*(limit-1)+2,2)

A∩B∩C:提前在A盒、B盒、C盒中放入limit+1个球,让剩下的球随便放,方案数为C(n-3*(limit-1)+2,2)

注意:上面三个的前提是还有剩余的球,如果剩余的球<=0,则方案数为0

代码如下 

class Solution {
    typedef long long LL;
public:
    LL C2(LL n)//计算C(n,2)
    {
        if(n>1)
            return n*(n-1)/2;
        else
            return 0;
    }
    long long distributeCandies(int n, int limit) {
        return C2(n+2)-3*C2(n-(limit+1)+2)+3*C2(n-2*(limit+1)+2)-C2(n-3*(limit+1)+2);
    }
};

三、重新排序后包含指定子字符串的字符串的数目 

这题也能用容斥原理来做:(题目中是小写,下面用大写代替)

A集合:L没有出现的方案数                                                                                25^n

B集合:E没有出现或只出现一次的方案数                                                          25^n+n*25^(n-1)

C集合:T没有出现的方案数                                                                                25^n

A∩B:L没有出现 并且 E没有出现或只出现一次的方案数                                   24^n+n*24^(n-1)

A∩C:L没有出现 并且 T没有出现的方案数                                                         24^n

B∩C:T没有出现 并且 E没有出现或只出现一次的方案数                                   24^n+n*24^(n-1)

A∩B∩C:L没有出现 并且 T没有出现 并且 E没有出现或只出现一次的方案数    23^n+n*23^(n-1)

不合法方案数(容斥原理):A+B+C-A∩B-A∩B-A∩B+A∩B∩C

总的方案数:26^n

计算幂,要用到快速幂的算法,时间复杂度为O(logn) 

代码如下

class Solution {
    typedef long long LL;
    const int MOD=1e9+7;
public:
    //快速幂
    LL POW(LL a,LL b)//a^b
    {
        int res=1;
        while(b){
            if(b&1) res=(res*a)%MOD;
            a=(a*a)%MOD;
            b>>=1;
        }
        return res;
    }
    int stringCount(int n) {
        //公式可以化简如下
        LL ans=POW(26,n)-((75+n)*POW(25,n-1)-(72+2*n)*POW(24,n-1)+(23+n)*POW(23,n-1));
        return (ans%MOD+MOD)%MOD;
    }
};

当然如果你没想到或者没学过容斥原理,这题还能用分组背包来求解,问题转化为:每次在'a'-'z'中选择一个字母,要求最后选择了至少1个L,1个T,2个E的方案数,时间复杂度为O(n)

代码如下

class Solution {
    const int MOD=1e9+7;
public:
    int stringCount(int n) {
        long long memo[n+1][2][2][3];
        memset(memo,-1,sizeof(memo));
        function<int(int,int,int,int)>dfs=[&](int i,int L,int T,int E)->int{
            if(i==0)
                return L==0&&T==0&&E==0;
            if(memo[i][L][T][E]!=-1) return memo[i][L][T][E];
            long long res=0;
            res+=dfs(i-1,0,T,E);//选择L
            res+=dfs(i-1,L,0,E);//选择T
            res+=dfs(i-1,L,T,max(E-1,0));//选择E
            res+=(long long)dfs(i-1,L,T,E)*23;//选择其他的字母
            return memo[i][L][T][E]=res%MOD;
        };
        return dfs(n,1,1,2);
    }
};

四、购买物品的最大开销

 

这题反倒是没什么难点, 我们根据题意,就能猜到小天数*小的商品价格得到的乘积之和为最大开销(根据排序不等式可知),接下来,只要证明我们能在某天买到与之对应的小的商品价格,这很容易证明:因为我们每次选择都是在每一行剩余元素的最小值组成的集合中,即我们可以选到剩余所有数中的最小值。

代码如下

class Solution {
public:
    long long maxSpending(vector<vector<int>>& values) {
        int n=values.size(),m=values[0].size();
        vector<int>dp(m*n);
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                dp[i*m+j]=values[i][j];
            }
        }
        sort(dp.begin(),dp.end());
        long long ans=0;
        for(int i=0;i<m*n;i++){
            ans=(ans+(long long)(i+1)*dp[i]);
        }
        return ans;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1219854.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

@Autowired 注入Mapper接口时报红色下划线警告

问题描述 在使用Autowired 注入Mapper接口时报红色下划线警告&#xff0c;虽然对代码没有什么影响可以正常执行&#xff0c;但是作为代码猿的我看着这个报红的就很不舒服&#xff0c;就想着让他不报红 问题描述&#xff1a; Autowired 自动注入&#xff0c;首先要求被自动注入…

精密云工程:智能激活业务速率 ——华为云11.11联合大促倒计时 仅剩3日

现新客3.96元起&#xff0c;下单有机会抽HUAWEI P60 Art&#xff0c;福利仅限双十一&#xff0c;机会唾手可得&#xff0c;立即行动&#xff01; 双十一购物节来临倒计时&#xff0c;华为云备上多款增值产品&#xff0c;以最优品质迸发冬日技术热浪&#xff0c;满足行业技术应用…

ROS 学习应用篇(九)ROS中launch文件的实现

launch文件就好比一个封装好的命令库&#xff0c;我们按照在终端中输入的代码指令&#xff0c;全部按照launch语言格式封装在一个launch文件中&#xff0c;这样以后执行的时候&#xff0c;就可以不用开很多终端&#xff0c;一条一条输入代码指令。 lauch文件的语言风格很想我之…

Redis(列表List)

使用LPUSH从头部添加元素&#xff0c;可以一次添加一个或多个。 使用LRANGE 查看列表中的数据&#xff0c;0表示起始位置&#xff0c;-1表示结束位置。 当然也可以使用RPUSH来从尾部添加元素。 可以使用RPOP从尾部删除元素&#xff0c;会返回删除的元素的值。 同理使用LPOP…

【python基础】用户输入和while循环详解

文章目录 一. 函数input()的工作原理1. 编写清晰的程序2. 使用int()来获取数值输入3. 求模运算符 二. while循环简介1. 使用while循环2. 让用户选择何时退出3. 使用标志4. 使用break退出循环5. 在循环中使用continue 三. 使用while循环处理列表和字典1. 在列表之间移动元素2. 删…

HIKVISION iSecure Center RCE 海康威视综合安防管理平台任意文件上传 POCEXP

参考:GitHub - Sweelg/HIKVISION_iSecure_Center-RCE: HIKVISION iSecure Center RCE 海康威视综合安防管理平台任意文件上传 POC&EXP&#xff08;一键getshell&#xff09; 速修&#xff01;海康威视综合安防RCE已被用于勒索 近日&#xff0c;勒索团伙利用海康威视综合安防…

Redis篇---第三篇

系列文章目录 文章目录 系列文章目录前言一、为什么 Redis 需要把所有数据放到内存中?二、Redis 的同步机制了解是什么?三、pipeline 有什么好处,为什么要用 pipeline?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到…

「校园 Pie」 系列活动正式启航,首站走进南方科技大学!

PieCloudDB 社区校园行系列活动「校园 Pie」已正式启动。「校园 Pie」旨在促进数据库领域的学术交流&#xff0c;提供一个平台让学生们了解最新的数据库发展趋势和相关技术应用。 在「校园 Pie」系列活动中&#xff0c;PieCloudDB 社区将携拓数派技术专家&#xff0c;社区大咖…

我们应该如何理解Java集合框架的关键知识点?

我们应该如何理解Java集合框架的关键知识点&#xff1f; java集合是教存取数据的一个容器&#xff0c;涵盖了各种存和取的方式&#xff0c;应用在不同的工作场景中&#xff0c;要想了解java集合的相关知识&#xff0c;建议先好好学习一下数据结构这本书。最近很多小伙伴找我&am…

【2023高交会成绩单出炉】Gooxi斩获“AIC年度标杆应用奖”大奖

第25届中国国际高新技术成果交易会&#xff08;简称“高交会”&#xff09;在深圳盛大开幕&#xff0c;作为高交会人工智能板块的重点活动之一&#xff0c;11.16日的第八届人工智能领袖大会的AIC年度奖项评选环节备受关注&#xff0c;Gooxi从多家入围企业中脱颖而出&#xff0c…

【广州华锐互动】VR可视化政务服务为公众提供更直观、形象的政策解读

虚拟现实&#xff08;VR&#xff09;技术正在逐渐应用于政务服务领域&#xff0c;为公众提供更加便捷、高效和个性化的服务体验。通过VR眼镜、手机等设备&#xff0c;公众可以在虚拟环境中参观政务服务中心&#xff0c;并根据自己的需求选择不同的办事窗口或事项进行咨询和办理…

【Android】如何使用模拟器调试安卓项目

1、电脑安装逍遥模拟器&#xff0c;用来跑安卓项目。安装好模拟器之后&#xff0c;直接起安卓项目&#xff0c;自动会在选择设备处显示 2、如果前端是安卓后端是其他语言的话&#xff0c;这种前后端分离的模式&#xff0c;需要监听端口&#xff0c;原因是运行安卓和后端编译器都…

【JVM】内存区域划分、类加载机制(双亲委派模型图解)、垃圾回收(可达性分析、分代回收)

一、JVM简介 JVM (Java虚拟机) 是执行Java字节码的虚拟机。它是Java平台的核心&#xff0c;并且为Java代码提供了跨平台的能力。JVM 是一种虚拟的计算机&#xff0c;在其上运行的程序是Java字节码&#xff0c;它提供了Java代码在不同操作系统和硬件平台上执行的能力。JVM 将Ja…

射频与微波综合测试仪-4958手持式微波综合测试仪

4958 微波综合测试仪 频率范围&#xff1a;1MHz&#xff5e;20GHz 4958手持式微波综合测试仪测量频率范围可达1MHz~20GHz&#xff0c;集电缆和天线驻波比测试、不连续点故障定位测试、插入损耗和增益测试、频谱分析、功率测量等多种功能于一体&#xff0c;携带方便&…

Unity中Shader纹理的多级渐远Mipmap

文章目录 前言一、什么是Mipmap二、Mipmap能带来什么好处1、增加缓存命中率&#xff0c;减少像素抖动感2、可配合质量设置来分级加载&#xff0c;减少不同配置下的内存 二、我们在Shader中实现一下该效果1、我们先布置一个简单的棋盘格&#xff0c;用于测试纹理的多级效果2、我…

【论文阅读】2736. 最大和查询-2023.11.17

题目&#xff1a; 2736. 最大和查询 给你两个长度为 n 、下标从 0 开始的整数数组 nums1 和 nums2 &#xff0c;另给你一个下标从 1 开始的二维数组 queries &#xff0c;其中 queries[i] [xi, yi] 。 对于第 i 个查询&#xff0c;在所有满足 nums1[j] > xi 且 nums2[j]…

陌陌附近人打招呼脚本,可自动回复消息,按键精灵开源脚本

用按键写的一个陌陌自动打招呼发送指定话术消息的一个脚本&#xff0c;它还会检测对方的消息&#xff0c;然后自动回复指定信息&#xff0c;下面是UI界面和代码&#xff0c;你可以直接粘贴到自己的按键精灵里面运行&#xff0c;不会出错&#xff0c;已经测试过。 UI界面&#…

vue中使用echarts实现省市地图绘制,根据数据显示不同区域颜色,点击省市切换,根据经纬度打点

一、实现效果 使用echarts实现省市地图绘制根据数据不同显示不同区域颜色实现省市地图点击切换效果实现地图上根据经纬度打点 二、实现方法 1、安装echarts插件 npm install echarts --save2、获取省市json数据 https://datav.aliyun.com/portal/school/atlas/area_select…

vue 表单重置功能

1、标签加上ref属性&#xff0c;名称自定义 <el-form ref"searchForm"></el-form>2、表单项标签添加prop属性&#xff0c;prop属性需要与input框绑定v-model的属性一致 <el-form-item label"名称" prop"name"><el-input …

大数据的技术运用:探索未来的无限可能性

随着科技的不断进步和社会信息的快速增长&#xff0c;大数据已成为一个热门话题。本文将探讨大数据技术在多个领域的应用&#xff0c;以及它对未来的影响和无限可能性。 导言 在过去的几十年里&#xff0c;大数据技术取得了惊人的发展&#xff0c;它不仅改变了企业的经营方式&a…