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

embedded/2024/9/25 10:36:49/

动态规划】数组中数字和为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 100int 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 151  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  00  1  2  3  4  5  6  7  8  9 10 11 12 13 14 151  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  00  1  2  3  4  5  6  7  8  9 10 11 12 13 14 151  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  00  1  2  3  4  5  6  7  8  9 10 11 12 13 14 151  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  00  1  2  3  4  5  6  7  8  9 10 11 12 13 14 151  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  00  1  2  3  4  5  6  7  8  9 10 11 12 13 14 151  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  40  1  2  3  4  5  6  7  8  9 10 11 12 13 14 151  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.ppmy.cn/embedded/35159.html

相关文章

Linux网络-部署YUM仓库及NFS共享服务

目录 一.YUM仓库服务 1.YUM概述 1.1.YUM&#xff08;Yellow dog Updater Modified&#xff09; 2.准备安装源 2.1.软件仓库的提供方式 2.2.RPM软件包的来源 2.3.构建CentOS 7 软件仓库 2.4.在软件仓库中加入非官方RPM包组 3.一键安装软件包的工具&#xff1a; 好处&a…

知到java笔记(4.1--继承的用法以及this和super的用法)

格式&#xff1a; 例子&#xff1a; get set获取父类的私有变量 private属性 this和super区别&#xff1a; this用法 super用法 例子

[安全开发]如何搭建一款自己的网安微信机器人

前言 hxd写的一个微信网安机器人。 原理 基于HOOK的微信机器人&#xff0c;以往的机器人大多数为协议机器人&#xff0c;封号概率极大&#xff08;下面会详细讲解hook和协议的区别&#xff09;&#xff0c;而HOOK机制的大大减小了封号几率。 什么是协议机器人&#xff1f; …

文本转图表的AI工具-Chart-GPT

Chart-GPT Chart-GPT一款基于 GPT 实现的开源工具&#xff0c;可在几秒内&#xff0c;将文本快速转换为各种图表。用户只需在输入字段中输入数据说明和所需的图表类型&#xff0c;Chart-GPT的后台生成器即可建出多种类型的图表&#xff0c;包括条形图、折线图、组合图、散点图、…

大数据技术概述_4.大数据的应用领域

1.制造业的应用 制造业目前正在向信息化和自动化的方向发展。在产品的设计、生产和销售中&#xff0c;越来越多的企业使用计算机辅助设计&#xff08;CAD&#xff09;、计算机辅助制造&#xff08;CAM&#xff09;等软件&#xff0c;数控机床、传感器等设备&#xff0c;物料需求…

免费分享一套微信小程序商城系统(电商系统)(SpringBoot+Vue3)【至尊版】,帅呆了~~

大家好&#xff0c;我是java1234_小锋老师&#xff0c;自己原创写了一个不错的微信小程序商城系统(电商系统)(SpringBootVue3)【至尊版】&#xff0c;免费分享下哈。 项目视频演示 【免费】微信小程序商城系统(电商系统)(SpringBootVue3) 【至尊版】Java毕业设计_哔哩哔哩_bi…

猜数字游戏

OK了诸君&#xff0c;五一小长假正式结束了&#xff0c;各位玩的怎么样呢&#xff1f;不管再怎么放肆开心&#xff0c;现在咱们也得把这个心往回拉一拉&#xff0c;学习方面咱们扬帆再起航&#xff0c;假期方面静静期待暑假哈哈哈 言归正传昂&#xff0c;这一期咱们主要是利用…

C++ 重载 [] 运算符

刚开始我是震惊的! 我从未想过[]下居然有逻辑! 从接触程序设计语言开始 曾因会使用a[0]访问数组元素而沾沾自喜 曾认为[] ,理应是访问数组的一种方式 曾认为[]只是一个无情的标识! 所以 当我们写下a[0]时,究竟是为了什么? 是为了找到a[0]对应的值 那么如何能找到它对应…