【题解】【动态规划01背包问题】—— [NOIP2012 普及组] 摆花

news2025/2/27 16:41:23

【题解】【动态规划01背包问题】—— [NOIP2012 普及组] 摆花

[NOIP2012 普及组] 摆花

通往洛谷的传送门

题目描述

小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共 m m m 盆。通过调查顾客的喜好,小明列出了顾客最喜欢的 n n n 种花,从 1 1 1 n n n 标号。为了在门口展出更多种花,规定第 i i i 种花不能超过 a i a_i ai 盆,摆花时同一种花放在一起,且不同种类的花需按标号的从小到大的顺序依次摆列。

试编程计算,一共有多少种不同的摆花方案。

输入格式

第一行包含两个正整数 n n n m m m,中间用一个空格隔开。

第二行有 n n n 个整数,每两个整数之间用一个空格隔开,依次表示 a 1 , a 2 , ⋯   , a n a_1,a_2, \cdots ,a_n a1,a2,,an

输出格式

一个整数,表示有多少种方案。注意:因为方案数可能很多,请输出方案数对 1 0 6 + 7 10^6+7 106+7 取模的结果。

输入输出样例

输入 #1

2 4
3 2

输出 #1

2

提示

【数据范围】

对于 20 % 20\% 20% 数据,有 0 < n ≤ 8 , 0 < m ≤ 8 , 0 ≤ a i ≤ 8 0<n \le 8,0<m \le 8,0 \le a_i \le 8 0<n8,0<m8,0ai8

对于 50 % 50\% 50% 数据,有 0 < n ≤ 20 , 0 < m ≤ 20 , 0 ≤ a i ≤ 20 0<n \le 20,0<m \le 20,0 \le a_i \le 20 0<n20,0<m20,0ai20

对于 100 % 100\% 100% 数据,有 0 < n ≤ 100 , 0 < m ≤ 100 , 0 ≤ a i ≤ 100 0<n \le 100,0<m \le 100,0 \le a_i \le 100 0<n100,0<m100,0ai100

NOIP 2012 普及组 第三题

解法1.二维 d p dp dp

1.1.思路解析

    这道题可以用01背包问题的模型来做。

    首先,还是动态规划五步走:

1.抽象问题:在 n n n个数中分别取一个数 p ≤ a i p\leq a_i pai,使得每一个 p p p的和为 m m m
2.状态:dp[i][j]代表当前只放前 i i i种花刚好放置 j j j盆的方法数。
3.初始条件:dp[0][0]=1
4.状态转移方程:
d p [ i ] [ j ] = ∑ k = 1 m i n ( a [ i ] , j ) d p [ i − 1 ] [ j − k ] dp[i][j]=\sum_{k=1}^{min(a[i],j)}dp[i-1][j-k] dp[i][j]=k=1min(a[i],j)dp[i1][jk]
5.答案:dp[n][m]

    请听我慢慢解析。

    这里的状态的定义和初始条件等都跟01背包问题的模型相似。不会的请看到这里来。

    这里主要讲一下动态转移方程的推导。

    这道题跟 01 01 01背包问题的模型不同的是, 01 01 01背包问题只有选或者不选某样物品两种状态。可在这里,我们可以选第 i i i件物品 0 0 0 a i a_i ai中的所有数量。

    也就是说,我们其实只需要把不取这个物品,这个物品取一件,取两件……取 a i a_i ai件的方案数用一个循环累加起来就行了。注意,这里不取这个物品的方案数也要加上。

    还要注意一件事,如果 a i > j ( 当前放置的花的总数量 ) a_i>j(当前放置的花的总数量) ai>j(当前放置的花的总数量),可不能取超过 m m m盆。即这种花我们最多取 m m m盆,所以最后一重循环的判断条件是k<=min(a[i],j)

    如果看不懂的话那就请看代码。

    最后提醒一句,记得取模 1 0 6 + 7 10^6+7 106+7

1.2.AC代码

#include<bits/stdc++.h>
using namespace std;
#define MAXN 110
const int mod=1000007;//模数
int n,m,a[MAXN],dp[MAXN][MAXN];//01背包
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>a[i];
    dp[0][0]=1;//初始条件,选前0种花摆0盆只有一种方法数,就是不摆
    for(int i=1;i<=n;i++)//枚举物品种类
        for(int j=0;j<=m;j++)//枚举盆数
            for(int k=0;k<=min(a[i],j);k++)//从这个种类里拿出1,2,...参与摆花
                dp[i][j]=(dp[i][j]+dp[i-1][j-k])%mod;//状态转移方程
    cout<<dp[n][m];
	return 0;
}

此算法的时间复杂度是 O ( n m 2 ) O(nm^2) O(nm2),超时警告!

解法2.一维 d p dp dp

2.1.思路解析

    如果不懂滚动数组优化的同学们可以先走了。

    这道题的优化基本没变,就是要注意,由于滚动数组会保存上次更新后的值,所以将第三重循环的 k = 0 k=0 k=0改成 k = 1 k=1 k=1

2.2.AC代码

#include<bits/stdc++.h>
using namespace std;
#define MAXN 110//模数
const int mod=1000007;
int n,m,a[MAXN],dp[MAXN];//01背包 
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>a[i];
    dp[0]=1;//初始条件,摆0盆只有一种方法数,就是不摆
    for(int i=1;i<=n;i++)//枚举物品种类 
        for(int j=m;j>=0;j--)//枚举盆数
            for(int k=1;k<=min(a[i],j);k++)//从这个种类里拿出1,2,...参与摆花
                dp[j]=(dp[j]+dp[j-k])%mod;//状态转移方程
    cout<<dp[m];
	return 0;
}

3.扩展:前缀和优化

    在上面的代码中,由于第三重循环求的就是 d p [ 1 ]   d p [ j − 1 ] dp[1]~dp[j-1] dp[1] dp[j1]这一区间的和,可以考虑用前缀和优化。因为我懒 篇幅关系,这里就不详细解说了。

喜欢就订阅此专辑吧!

【蓝胖子编程教育简介】
蓝胖子编程教育,是一家面向青少年的编程教育平台。平台为全国青少年提供最专业的编程教育服务,包括提供最新最详细的编程相关资讯、最专业的竞赛指导、最合理的课程规划等。本平台利用趣味性和互动性强的教学方式,旨在激发孩子们对编程的兴趣,培养他们的逻辑思维能力和创造力,让孩子们在轻松愉快的氛围中掌握编程知识,为未来科技人才的培养奠定坚实基础。

欢迎扫码关注蓝胖子编程教育
在这里插入图片描述

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

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

相关文章

python基础知识(十一)面向过程,面向对象,对象属性,魔法方法,继承,私有权限

目录 面向过程是什么 什么是面向对象&#xff1f; 面向对象的三大特性&#xff1a; 继承 多态 类 对象 self关键字 对象属性 类外面访问属性 类内部获取属性 魔法方法 无参init()方法 有参init()方法 str()方法 del()方法 继承基础 什么是继承 单继承 多继…

Javascript笔试题目(六)

1.如何使用JS实现Promise 对象?请写出具体代码 Promise其实也不难-CSDN博客 Javascript 手写一个Promise_javascript中手写promise ?-CSDN博客 Promise其实也不难-CSDN博客 题目要求我们使用JavaScript实现一个Promise对象。对此我们可以基于Promise/A规范的要求进行实现Prom…

面试-2024年7月16号

面试-2024年7月16号 自我介绍Mysql主从复制是做了一个什么样的集群&#xff1f;在Mysql的使用过程中遇到过哪些问题&#xff1f;mysql迁移具体步骤mysql漏洞修复是怎么做的。mysql的容灾方案&#xff08;灾备恢复机制&#xff09;。redis多节点怎么部署的redis的备份与恢复、迁…

电源中的“冷地”和“热地”

最近硬件同事在弄开关电源相关项目&#xff0c;由于其第一次做开关电源&#xff0c;并不懂冷地和热地的区别&#xff0c;出现示波器探头接地夹夹“热地”导致实验室多次跳闸&#xff0c;最严重时把板子给炸了。为了了解冷地和热地的如何辨别以及为什么热地带电这些知识&#xf…

【从零开发Mybatis】引入XNode和XPathParser

引言 在上文&#xff0c;我们发现直接使用 DOM库去解析XML 配置文件&#xff0c;非常复杂&#xff0c;也很不方便&#xff0c;需要编写大量的重复代码来处理 XML 文件的读取和解析&#xff0c;代码可读性以及可维护性相当差&#xff0c;使用起来非常不灵活。 因此&#xff0c…

JavaEE 多线程第二节 (多线程的简单实现Thread/Runable)

1. 创建线程&#xff08;继承 Thread 类&#xff09;步骤&#xff1a; 继承 Thread 类&#xff1a; 创建一个类并继承 Thread 类&#xff0c;然后重写 run() 方法&#xff0c;在该方法中写入线程执行的代码 class MyThread extends Thread {Overridepublic void run()…

数据恢复超简单!9 个方法任你选!小白也能轻易恢复数据!

在当今数字化的世界中&#xff0c;数据恢复的重要性日益凸显。无论是工作中的重要文档&#xff0c;还是生活中的珍贵照片和视频&#xff0c;一旦丢失&#xff0c;都可能给我们带来极大的困扰。别担心&#xff0c;下面为大家介绍 9 个超简单的数据恢复方法&#xff0c;让小白也能…

C++基础面试题 | 什么是C++中的运算符重载?

文章目录 回答重点&#xff1a;示例&#xff1a; 运算符重载的基本规则和注意事项&#xff1a; 回答重点&#xff1a; C的运算符重载是指可以为自定义类型&#xff08;如类或结构体&#xff09;定义运算符的行为&#xff0c;使其像内置类型一样使用运算符。通过重载运算符&…

它思科技CTO聂玮奇:消除“AI幻觉”,搭建高可靠对话云平台丨数据猿专访

大数据产业创新服务媒体 ——聚焦数据 改变商业 近年来&#xff0c;大模型技术在全球范围内引起了广泛关注和应用热潮。 提到人工智能&#xff0c;很多人会想到它强大的运算能力和广泛的应用场景。如今&#xff0c;语言模型的发展如火如荼&#xff0c;但其中的“幻觉”问题却带…

基于SSM社区医院预约转诊管理系统JAVA|VUE|Springboot计算机毕业设计源代码+数据库+LW文档+开题报告+答辩稿+部署教+代码讲解

源代码数据库LW文档&#xff08;1万字以上&#xff09;开题报告答辩稿 部署教程代码讲解代码时间修改教程 一、开发工具、运行环境、开发技术 开发工具 1、操作系统&#xff1a;Window操作系统 2、开发工具&#xff1a;IntelliJ IDEA或者Eclipse 3、数据库存储&#xff1a…

SwiftUI 6.0(iOS 18)自定义容器值(Container Values)让容器布局渐入佳境(上)

概述 我们在之前多篇博文中已经介绍过 SwiftUI 6.0&#xff08;iOS 18&#xff09;新增的自定义容器布局机制。现在&#xff0c;如何利用它们对容器内容进行“探囊取物”和“聚沙成塔”&#xff0c;我们已然胸有成竹了。 然而&#xff0c;除了上述鬼工雷斧般的新技巧之外&…

STM32_实验1_建立新工程

1、使用STM32CubeIDE建立一个新工程 1.1选择时钟源为外部晶振时钟。 1.2选择调试方式为 serial wire&#xff08;串行线&#xff09;。 1.3配置时钟树. 1.4选择以 c 和 h 文件型式管理工程文件。 1.5生成 hex 可执行文件。&#xff08;完成后点击锤子&#xff09; 2.串口输出调…

鸿蒙进入“无人区”:该如何闯关?

按照华为方面的说法&#xff0c;“打造鸿蒙操作系统是三大战役&#xff0c;目前已经完成了底座和体验两大战役&#xff0c;第三大战役则是生态。”生态固然重要&#xff0c;但要让鸿蒙与当今世界主流操作系统抗衡&#xff0c;乃至成为新一代操作系统中的翘楚&#xff0c;其实还…

每个程序员都应该了解的硬件知识

作者:shizhaoyang 在追求高效代码的路上,我们不可避免地会遇到代码的性能瓶颈。为了了解、解释一段代码为什么低效,并尝试改进低效的代码,我们总是要了解硬件的工作原理。于是,我们可能会尝试搜索有关某个架构的介绍、一些优化指南或者阅读一些计算机科学的教科书(如:计…

卡码网KamaCoder 94. 城市间货物运输 I

题目来源&#xff1a;94. 城市间货物运输 I C题解1&#xff08;来源代码随想录&#xff09;&#xff1a;Bellman_ford 本题是经典的带负权值的单源最短路问题&#xff0c;此时就轮到Bellman_ford登场了。Bellman_ford算法的核心思想是 对所有边进行松弛n-1次操作&#xff08;…

【 ACM独立出版】第二届通信网络与机器学习国际学术会议(CNML 2024,10月25-27)

官方信息 会议官网&#xff1a;www.cn-ml.org The 2nd International Conference on Communication Networks and Machine Learningwww.cn-ml.org 时间地点&#xff1a;2024年10月25-27日 | 中国-河南-郑州 截稿时间&#xff1a;2024年10日19日 &#xff08;多轮截稿&#x…

51单片机的晾衣架控制系统【proteus仿真+程序+报告+原理图+演示视频】

1、主要功能 该系统由AT89C51/STC89C52单片机LCD1602显示模块温湿度传感器光照传感器步进电机按键、LED、蜂鸣器等模块构成。适用于智能晾衣架等相似项目。 可实现功能: 1、LCD1602实时显示温湿度、光照强度和手动/自动信息 2、温湿度传感器DHT11采集温湿度信息 3、光照传感…

【数据结构与算法初阶】顺序表(上)

什么语言实现不重要&#xff0c;理解了思路就行&#xff0c;本篇使用C语言实现 一.顺序表含义(重要) 首先&#xff0c;顺序表属于线性表中的一中&#xff0c;线性表可以用多种方式实现&#xff0c;顺序表只是其中的一种 --------- 线性表是啥呢&#xff0c;通俗的说&#xff0…

lego-loam imageProjection.cpp源码注释(一)

一、主函数 int main(int argc, char** argv){ros::init(argc, argv, "lego_loam");ImageProjection IP;ROS_INFO("\033[1;32m---->\033[0m Image Projection Started.");ros::spin();return 0; }主函数很简单&#xff0c;常规ros初始化ros::init&…

程序员35岁丢了工作,应该怎么活?

35岁对很多程序员来说是个敏感的年龄段。在这个阶段&#xff0c;许多程序员已经有了丰富的工作经验和较高的薪水&#xff0c;但同时也面临着职场上不可忽视的年龄压力。尤其在一些技术密集型的公司&#xff0c;35岁之后的程序员可能被认为“年纪大了”&#xff0c;不再是招聘市…