基础算法题——HDU6092 子集问题(0/1背包+思维)

本文详细介绍了如何解决HDU6092子集问题,通过动态规划结合0/1背包思想,找到满足条件的字典序最小的正数集合。文章提供了样例解释和解题步骤,以及相应的代码实现。
摘要由CSDN通过智能技术生成

一道巧妙的 dp 题~

题目

题目链接
给定n,m和数组b0 ~ bm (m+1个数),求出一个正数集合A:a1 ~ an,满足:集合 A 中每个子集的和为 i 的个数为 bi,并输出字典序最小的A。(n <= 50, m<=104, bi<=2n

输入:
第一行包含一个数字,即测试用例的数量T。对于每个测试用例,第一行包含两个数字n,m。第二行包含数字为数组 b 。
输出:
对于每个测试用例,用数字打印一行。保证至少有一个解决方案。如果有不同的解决方案,打印字典序最小的一个为数组 a 。

样例输入
2
2 3
1 1 1 1
3 3
1 3 3 1
样例输出:
1 2
1 1 1


样例说明

①、
b = {1,1,1,1}
①、空集的数量为1
②、子集和为1的数量为1
③、子集和为2的数量为1
④、子集和为3的数量为1
满足上述条件且字典序最小的数组
a = {1,2}

②、
b = {1,3,3,1}
①、空集的数量为1
②、子集和为1的数量为3
③、子集和为2的数量为3
④、子集和为3的数量为1
满足上述条件且字典序最小的数组
a = {1,1,1}


解题思路

①、 初始化
dp[i]:现 a 数组中子集和为 i 的个数
b[i]:要求子集和为 i 的个数
dp[0]:空集个数始终为1

②、若子集和 i 的数量( dp[i] )不满足题目要求( b[i] )则直接向 a 数组中加入值为 i 的元素,使字典序最小

③、a 数组每加入一个新的元素则更新 dp 数组
0/1背包思维更新 dp 数组
现 a 数组中子集和为 i 的个数 = 原先 a 数组中子集和为 i 的个数 + a 数组中子集和为 i-k 的个数
递推式:dp[i] = dp[i] + dp[i-k]


实现代码
#include<stdio.h>
#include<memory.h> 
int a[10010], b[10010
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值