【动态规划】数组中数字和为sum的方案个数

【动态规划】数组中数字和为sum的方案个数

给定一个有 n n n个正整数的数组 a 和一个正整数 s u m sum sum,求选择数组 a
部分数字和为 s u m sum sum的方案数。若两种选取方案有一个数字的下标不一样,则认为是不同的方案。

输入描述:输入为两行,第一行为两个正整数 a a a s u m sum sum,第二行为 n n n 个正整数a[i],以空格隔开。
输出描述:输出所求的方案数。
设计算法实现上述需求,并分析算法的时间复杂度。

代码实现

#include<bits/stdc++.h>
using namespace std;

#define MAX 100

int a[MAX] = {5,5,10,2,3};
int n = 5,sum=15;

void printNum(int num[MAX][MAX],int n,int sum);

int getPro(int a[],int sum,int n)
{
    int res=0;
    int dp[MAX][MAX]={0};
    if(sum==0)return 0;

    for(int i=0;i<=n;i++)
    {
        dp[i][0]=1;
    }
    printNum(dp,n,sum);
    for(int i=1;i<=sum;i++)
    {
        dp[0][i]=0;
    }
    
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=sum;j++)
        {
            if(a[i-1]>j)
            {
                dp[i][j] = dp[i-1][j];//这时候背包已经装不下新的物品了,所以可装的物品应该不变,即继承了上一行的值即可    ->    dp[i][j] = dp[i-1][j]
            }
            else
            {
                dp[i][j] = dp[i-1][j]+dp[i-1][j-a[i-1]];
            }
        }
        printNum(dp,n,sum);
    }
    printNum(dp,n,sum);
    return dp[n][sum];
}

void printNum(int num[MAX][MAX],int n,int sum){
    cout << "\t  ";
    for(int i=0;i<=sum;i++)
    {
        printf("%2d ",i);
    }
    cout << endl;

    printf("\t  ");
        for(int j=0;j<=sum;j++)
        {
            printf("%2d ",num[0][j]);
        }
        cout << endl;
        
    for(int i=1;i<=n;i++)
    {
        printf("a[%d]: %2d |",i-1,a[i-1]);
        for(int j=0;j<=sum;j++)
        {
            printf("%2d ",num[i][j]);
        }
        cout << endl;
    }
    cout << endl;
    return;
}

int main()
{
    int res = getPro(a,sum,n);
    cout << "共有" << res << "种方案。";
    return 0;
}

核心算法

int getPro(int a[],int sum,int n)
{
    int res=0;
    int dp[MAX][MAX]={0};
    if(sum==0)return 0;

    for(int i=0;i<=n;i++)
    {
        dp[i][0]=1;
    }
    printNum(dp,n,sum);
    for(int i=1;i<=sum;i++)
    {
        dp[0][i]=0;
    }
    
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=sum;j++)
        {
            if(a[i-1]>j)
            {
                dp[i][j] = dp[i-1][j];//这时候背包已经装不下新的物品了,所以可装的物品应该不变,即继承了上一行的值即可    ->    dp[i][j] = dp[i-1][j]
            }
            else
            {
                dp[i][j] = dp[i-1][j]+dp[i-1][j-a[i-1]];
            }
        }
        printNum(dp,n,sum);
    }
    printNum(dp,n,sum);
    return dp[n][sum];
}

主循环

for(int i=1;i<=n;i++)//i从0到n
    {
        for(int j=1;j<=sum;j++)//j从1到sum,因为0位置已经赋值了
        {

判断新增物品的质量(v[i])

            if(a[i-1]>j)
            {
                dp[i][j] = dp[i-1][j];
            }

情况一: 新增物品的质量(v[i]) 大于所需要合成背包的质量 j

这时候背包已经装不下新的物品了,所以可装的物品应该不变,
即继承了上一行的值即可

d p [ i ] [ j ] = d p [ i − 1 ] [ j ] ( a [ i ] > j ) dp[i][j] = dp[i-1][j]\tag{$a[i]> j$} dp[i][j]=dp[i1][j](a[i]>j)

            else
            {
                dp[i][j] = dp[i-1][j]+dp[i-1][j-a[i-1]];
            }

情况二: 新增的物品质量小于等于需要合成背包的质量 j
现在可构成质量为j的背包的方法数 = 上一行构成j的值 + 上一行构成j-a[i]的值

d p [ i ] [ j ] = d p [ i − 1 ] [ j ] + d p [ i − 1 ] [ j − a [ i ] ] ( a [ i ] ≤ j ) dp[i][j] = dp[i-1][j] + dp[i-1][j- a[i] ]\tag{$a[i]\leq j$} dp[i][j]=dp[i1][j]+dp[i1][ja[i]](a[i]j)

        }
    }

运行结果

为了方便观察,采用表格展示:

           0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
           1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
a[0]:  5 | 1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
a[1]:  5 | 1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
a[2]: 10 | 1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
a[3]:  2 | 1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
a[4]:  3 | 1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0

           0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
           1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
a[0]:  5 | 1  0  0  0  0  1  0  0  0  0  0  0  0  0  0  0
a[1]:  5 | 1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
a[2]: 10 | 1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
a[3]:  2 | 1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
a[4]:  3 | 1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0

           0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
           1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
a[0]:  5 | 1  0  0  0  0  1  0  0  0  0  0  0  0  0  0  0
a[1]:  5 | 1  0  0  0  0  2  0  0  0  0  1  0  0  0  0  0
a[2]: 10 | 1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
a[3]:  2 | 1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
a[4]:  3 | 1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0

           0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
           1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
a[0]:  5 | 1  0  0  0  0  1  0  0  0  0  0  0  0  0  0  0
a[1]:  5 | 1  0  0  0  0  2  0  0  0  0  1  0  0  0  0  0
a[2]: 10 | 1  0  0  0  0  2  0  0  0  0  2  0  0  0  0  2
a[3]:  2 | 1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
a[4]:  3 | 1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0

           0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
           1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
a[0]:  5 | 1  0  0  0  0  1  0  0  0  0  0  0  0  0  0  0
a[1]:  5 | 1  0  0  0  0  2  0  0  0  0  1  0  0  0  0  0
a[2]: 10 | 1  0  0  0  0  2  0  0  0  0  2  0  0  0  0  2
a[3]:  2 | 1  0  1  0  0  2  0  2  0  0  2  0  2  0  0  2
a[4]:  3 | 1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0

           0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
           1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
a[0]:  5 | 1  0  0  0  0  1  0  0  0  0  0  0  0  0  0  0
a[1]:  5 | 1  0  0  0  0  2  0  0  0  0  1  0  0  0  0  0
a[2]: 10 | 1  0  0  0  0  2  0  0  0  0  2  0  0  0  0  2
a[3]:  2 | 1  0  1  0  0  2  0  2  0  0  2  0  2  0  0  2
a[4]:  3 | 1  0  1  1  0  3  0  2  2  0  4  0  2  2  0  4

           0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
           1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
a[0]:  5 | 1  0  0  0  0  1  0  0  0  0  0  0  0  0  0  0
a[1]:  5 | 1  0  0  0  0  2  0  0  0  0  1  0  0  0  0  0
a[2]: 10 | 1  0  0  0  0  2  0  0  0  0  2  0  0  0  0  2
a[3]:  2 | 1  0  1  0  0  2  0  2  0  0  2  0  2  0  0  2
a[4]:  3 | 1  0  1  1  0  3  0  2  2  0  4  0  2  2  0  4

共有:4种方案。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深入了解C/C++的内存区域划分

&#x1f525;个人主页&#xff1a;北辰水墨 &#x1f525;专栏&#xff1a;C学习仓 本节我们来讲解C/C的内存区域划分&#xff0c;文末会附加一道题目来检验成果&#xff08;有参考答案&#xff09; 一、大体有哪些区域&#xff1f;分别存放什么变量开辟的空间&#xff1f; …

ROS 2边学边练(43)-- 利用GTest写一个基本测试(C++)

前言 在ROS&#xff08;Robot Operating System&#xff09;中&#xff0c;gtest&#xff08;Google Test&#xff09;是一个广泛使用的C测试框架&#xff0c;用于编写和执行单元测试。这些测试可以验证ROS节点、服务和消息等的正确性和性能。 如果我们需要在写的包中添加测试&…

红黑树

一、红黑树用在哪里 HashMap。Linux 进程调度 CFS。Epoll 事件块的管理。Nginx Timer 事件管理。&#xff08;key&#xff0c;value&#xff09;的形式&#xff0c;并且中序遍历是顺序的&#xff0c;红黑树是二叉排序树。 二、红黑树性质 每个节点是红色或者黑色。根节点是黑…

Mybatis进阶3--注解开发

先看&#xff1a; Mybatis进阶1-CSDN博客 Mybatis进阶2-CSDN博客 mybatis注解开发 前置&#xff1a;不需要xxxMapper..xml文件&#xff08;映射文件&#xff09; 在核心配置文件中&#xff1a;<mappers>标签只能使用&#xff1a;<package name"扫描的包&quo…

open-webui+ollama本地部署Llama3

前言 Meta Llama 3 是由 Meta 公司发布的下一代大型语言模型&#xff0c;拥有 80 亿和 700 亿参数两种版本&#xff0c;号称是最强大的开源语言模型。它在多个基准测试中超越了谷歌的 Gemma 7B 和 Mistral 7B Instruct 模型。 安装 1.gpt4all https://github.com/nomic-ai/…

记一次动态规划的采坑之旅, 741摘樱桃 https://leetcode.cn/problems/cherry-pickup/description/

首次看题目时&#xff0c;发现是困难。立马想到了&#xff0c;动态规划。 再看题目&#xff0c; 摘樱桃&#xff0c;还要返回摘两次&#xff0c;求摘最多的樱桃。 大脑第一反应就是&#xff1a; 先使用动态规划&#xff0c;找到 0 0 到 n-1 n-1处走过的最大樱桃&#xff0c; 并…

【码银送书第十九期】《图算法:行业应用与实践》

作者&#xff1a;嬴图团队 01 前言 在当今工业领域&#xff0c;图思维方式与图数据技术的应用日益广泛&#xff0c;成为图数据探索、挖掘与应用的坚实基础。本文旨在分享嬴图团队在算法实践应用中的宝贵经验与深刻思考&#xff0c;不仅促进业界爱好者之间的交流&#xff0c;…

AI不只是技术,更是一种思维方式

一、AI思维 1.个人&#xff1a;提升自己的综合能力&#xff0c;成为一名懂技术、懂设计、懂硬件、懂市场运营等知识的综合型人才 2.数据&#xff1a;从全局视角看数据流向&#xff0c;挖掘数据价值 3.产品&#xff1a;运用新技术&#xff0c;发掘新需求点&#xff0c;探索产…

AI智体的分级:从基于规则到基于LLM

摘要&#xff1a; AI智体被定义为感知环境、做出决策和采取行动的人工实体。受SAE&#xff08;汽车工程师学会&#xff09;自动驾驶6个级别的启发&#xff0c;AI智体也根据效用和强度进行分类&#xff0c;分为以下几个级别&#xff1a;L0——无AI&#xff0c;有工具&#xff0…

马常旭新歌《如愿》:音乐界的“旭日”再现

在这个春暖花开的季节&#xff0c;音乐界又迎来了一股清新的“旭日”气息。是的&#xff0c;就在2024年4月17日&#xff0c;马常旭的新歌《如愿》&#xff08;旭日版&#xff09;在网易云音乐上线了&#xff01;一年的等待&#xff0c;终于迎来了他的音乐回归&#xff0c;给我们…

C语言知识点补充——ASCLL码表

1、ASCLL码表 ASCII码表&#xff08;American Standard Code for Information Interchange&#xff09;是一种用于将字符编码为数字的标准。它定义了128个字符的编码方式&#xff0c;包括数字、字母、标点符号和控制字符等。每个字符都对应一个唯一的7位或8位二进制数 2、Ascl…

贪吃蛇项目(小白保姆级教程)

游戏介绍 游戏背景&#xff1a; 贪吃蛇游戏是经典的游戏项目之一&#xff0c;也是很简单的小游戏 实现背景&#xff1a; 这里我们是基于32位的Win32_API进行实现的 需要的知识点&#xff1a; C语言函数、枚举、结构体、动态内存管理、预处理指令、链表、Win32_API等 适合人群&a…

java中的字符串(String)常量池理解

下面创建String对象的方式一样吗&#xff1f; 上述程序创建对象类似&#xff0c;为什么s1和s2引用对象一样&#xff0c;但是s3和s4不一样呢&#xff1f; 在java程序中&#xff0c;许多基本类型的字面常量会经常用到&#xff0c;例如2,3.11&#xff0c;“hyy”等。为了提升程序…

C语言动态内存管理malloc、calloc、realloc、free函数、内存泄漏、动态内存开辟的位置等的介绍

文章目录 前言一、为什么存在动态内存管理二、动态内存函数的介绍1. malloc函数2. 内存泄漏3. 动态内存开辟位置4. free函数5. calloc 函数6. realloc 函数7. realloc 传空指针 总结 前言 C语言动态内存管理malloc、calloc、realloc、free函数、内存泄漏、动态内存开辟的位置等…

25.哀家要长脑子了---哈希表

1.525. 连续数组 - 力扣&#xff08;LeetCode&#xff09; 在我对通义千问的一番折磨下&#xff0c;终于弄清楚一点点了。哈希表存储前缀和数组值 用一个counter来记录nums中0、1数量差值的变化。 哈希表map存储某个特定的counter值首次出现的位置。counter的计算&#xff1a;…

【LeetCode 121】买卖股票的最佳时机

思路 思路&#xff1a; 所谓代码的复杂性来源于业务的复杂性&#xff0c;如果能够想清楚业务实现逻辑&#xff0c;就能够轻松写出代码&#xff1b; 假设当前是第i天&#xff0c;如何在第i天赚到最多的钱&#xff1f;需要在第i天之前以最低价买入股票&#xff1b; 所以需要求…

13 【PS作图】人物绘画理论-脸型

三庭五眼 三庭&#xff1a;脸的长度比例 &#xff08;1&#xff09;发际线到眉毛 &#xff08;2&#xff09;眉毛到鼻底 &#xff08;3&#xff09;鼻底到下巴 三个部分大致为三等分 五眼&#xff1a;脸的宽度比例 以眼睛长度为单位&#xff0c;把脸的宽度分成五等分&#x…

[极客大挑战 2019]PHP

1.通过目录扫描找到它的备份文件&#xff0c;这里的备份文件是它的源码。 2.源码当中涉及到的关键点就是魔术函数以及序列化与反序列化。 我们提交的select参数会被进行反序列化&#xff0c;我们要构造符合输出flag条件的序列化数据。 但是&#xff0c;这里要注意的就是我们提…

求解亲和数

【问题描述】 古希腊数学家毕达哥拉斯在自然数研究中发现&#xff0c;220的所有真约数&#xff08;即不是自身 的约数&#xff09;之和为&#xff1a; 1245101120224455110284。而284的所有真约数为1、2、4、71、142&#xff0c;加起来恰好为220。人 们对这样的数感到很惊奇&am…

五种主流数据库:窗口函数

SQL 窗口函数为在线分析系统&#xff08;OLAP&#xff09;和商业智能&#xff08;BI&#xff09;提供了复杂分析和报表统计的功能&#xff0c;例如产品的累计销量统计、分类排名、同比/环比分析等。这些功能通常很难通过聚合函数和分组操作来实现。 本文比较了五种主流数据库实…
最新文章