首页 > 其他分享 >leetcode2902 和带限制的子多重集合的数目

leetcode2902 和带限制的子多重集合的数目

时间:2025-01-12 19:55:03浏览次数:1  
标签:leetcode2902 多重 dp2 nums int 元素 std 集合 dp

给定数组nums[n]和整数l,r,nums中的元素可能会重复,要求从nums中选择若干个元素,其元素和在[l,r]内,有多少种不同方案,结果对1E9+7取模。注:空集合的结果为0,相等的元素之间没有区别。
1<=n<=2E4; 0<=nums[i]<=2E4; sum(nums[i])<=2E4; 0<=l<=r<=2E4

分析:
1、存在相等元素,且没有区别,可以看成是一个多重背包问题。
2、由于sum(nums[i])<=2E4,可以估算出不同元素的个数(记为m)不超过200,因为1+2+..+200>2E4。
3、如果用二进制优化,时间复杂度会超,因此要用类似单调队列优化dp的方式优化掉时间复杂度中的log,大致思路如下:
(1)状态转移方程:dp[i][j] = dp[i-1][j] + dp[i-1][j-v] + dp[i-1][j-2v] + dp[i-1][j-3v] + ...,可以看到第二维模v同余,即计算dp[i][j]时,只依赖dp[i-1]只与j同余的那些项。
(2)外层按余数0~v-1从小到大的顺序,内层按a, a+v, a+2v的顺序,计算dp。对于某个固定的余数,由于j较大时,未必有足够的相同元素,因此用滑动窗口来维护。
4、元素0需要单独处理。

int dq[20005];
class Solution {
public:
    int countSubMultisets(vector<int>& nums, int l, int r) {
        int n = nums.size();
        std::sort(nums.begin(), nums.end());
        std::vector<std::pair<int,int>> vp;
        int cnt0 = 0;
        for (int i = 0, j = 0; i < n; i = j) {
            for (j = i; j < n && nums[j] == nums[i]; j++);
            if (nums[i] == 0) {
                cnt0 = j - i;
            } else {
                vp.emplace_back(nums[i], j - i);
            }
        }
        int m = vp.size();
        std::vector<mint> dp1(r + 1), dp2(r + 1);

        for (int i = 0; i <= m; i++) {
            dp1[0] = 1;
        }
        for (int i = 1; i <= m; i++) {
            int val = vp[i-1].first;
            int cnt = vp[i-1].second;
            for (int j = 0; j < val; j++) {
                mint sum = 0;
                int L = 0, R = 0;
                for (int k = j; k <= r; k += val) {
                    sum += dp1[k];
                    dq[R++] = k;
                    if (dq[R-1] - dq[L] > val * cnt) {
                        sum -= dp1[dq[L++]];
                    }
                    dp2[k] = sum;
                }
            }
            std::swap(dp1, dp2);
        }
        mint ans = 0;
        for (int j = l; j <= r; j++) {
            ans += dp1[j];
        }
        if (cnt0) ans *= cnt0 + 1;
        return ans.val();
    }
};

标签:leetcode2902,多重,dp2,nums,int,元素,std,集合,dp
From: https://www.cnblogs.com/chenfy27/p/18667205

相关文章

  • Set 系列集合的深入理解与应用
    在Java中,Set系列集合是一个非常重要的集合框架,它提供了多种实现,每个实现都具有独特的特性,适用于不同的场景。本文将详细介绍Set系列集合的相关知识,包括其通用特性、各种实现类及其底层原理。一、Set集合的通用特性Set集合具有以下几个显著的特点:无序:这意味着元素的存......
  • JAVA之集合
    1、集合集合可以存储引用数据类型;集合不可以存储基本数据类型,若要存储,需封装成包装类;2、集合和数组的对比长度【数组长度固定,集合长度可变】存储类型【数组可以存基本数据类型和引用数据类型,集合可以存引用数据类型,若存储基本数据类型,需封装成包装类】3、ArrayList【打......
  • Redis 是一个开源的高性能键值对存储数据库,通常被用作缓存、消息队列和持久化数据库。
    Redis服务器是什么?Redis是一个开源的高性能键值对存储数据库,通常被用作缓存、消息队列和持久化数据库。Redis支持多种数据结构,如字符串、哈希、列表、集合、有序集合、位图等。它被广泛用于需要快速读写操作、低延迟的场景。Redis可以作为一个独立的数据库使用,也可以作为缓......
  • JNI原生基础类型与集合类型认识
    1.JNI基础类型认识:JNI类型与C++类型及JAVA类型的对应关系  2.JNI基础类型对应的JAVA类型3.基础类型使用示例jboolean_jbool=false;//uint8_t%u无符号8位整数jbyte_byte=0xff;//int8_t;%d有符号8位整数jchar_char=0xffff;//uint16_t;%u无符号......
  • 05容器篇(D2_集合 - D6_容器源码分析篇 - D2_LinkedList)
    目录本章目标一、基本介绍二、原理分析1.数据结构2.默认容量&最大容量3.扩容机制4.为什么LinkedList查询慢,增删快?1>为什么增删快?2>为什么查询慢?三、经典大厂面试题1.ArrayList的JDK1.8之前与之后的实现区别?2.List和Map区别?3.Array和ArrayList有何......
  • 05容器篇(D2_集合 - D6_容器源码分析篇 - D3_HashMap)
    目录本章目标一、基本介绍1.什么是HashMap?2.HashMap类的继承关系二、原理分析1.哈希表2.存储数据过程1>存储过程中相关属性2>存储过程图解3>存储过程源码分析3.底层数据1>什么是数据结构?2>HashMap的数据结构3>数据结构的源码三、源码分析1.HashMa......
  • (java) 集合体系
    集合集合的体系整个集合体系最大的就是单列集合Collection和双列集合(键值对)MapCollection接口下由两个子接口,分别为Set接口和List接口List系列集合:添加的元素是有序、可重复、有索引,例如ArrayListSet系列的集合:添加的元素是大部分无序、不重复、无索引(一)单列集合Coll......
  • Avalonia 元素集合实现Menus(图片资源文件绑定后不显示问题)
    <SplitViewIsPaneOpen="True"DisplayMode="Inline"OpenPaneLength="200"CompactPaneLength="60"><SplitView.Pane><GridMargin="0,5"><!--定义行--......
  • 集合框架笔记
    一、接口及实现类:Collection接口:子接口-----:1List接口:存储有序的,可重复的数据实现类:ArrayList(主要实现类)、LinkedList、Vector2Set接口:存储无序的、不可重复的数据(类似于集合)实现类:HashSet(主要实现类)、LinkedHashSet、TreeSetMap接口:key-value对--->键值对实......
  • Java学习,数组转集合
    Java中将数组转换为集合(例如 List)是一项常见的操作。Java提供了多种方法来实现这一功能,其中最简单和常用的方法是使用 java.util.Arrays 类和 java.util.Collections 类中的静态方法。数组转集合,示例:importjava.util.List;importjava.util.ArrayList;importjava.u......