牛客网 [编程题]数字和为sum的方法数

本文介绍了一道编程题目,要求计算数字和为特定值的方案数。通过动态规划降低时间复杂度,状态转移方程为dp[i][j]=dp[i-1][j-narr[i]]+dp[i-1][j],并给出了JavaScript实现。
题目描述:
给定一个有n个正整数的数组A和一个整数sum,求选择数组A中部分数字和为sum的方案数。
当两种选取方案有一个数字的下标不一样,我们就认为是不同的组成方案。
输入描述:
输入为两行:
 第一行为两个正整数n(1 ≤ n ≤ 1000),sum(1 ≤ sum ≤ 1000)
 第二行为n个正整数A[i](32位整数),以空格隔开。
输出描述:
输出所求的方案数
示例1
输入

5 15

5 5 10 2 3

输出

4


思路:

这道题用递归可以很方便地做出来,不过时间复杂度会比较大。用动态规划做可以解决这个问题,最重要的是要找到状态转移方程。dp[i][j]代表前i个数中数字和为j的方案数,有这样的关系:dp[i][j]=dp[i-1][j-narr[i]]+dp[i-1][j]; 表示前i个数中数字和为j的方案数=前i-1个数中数字和为 j减去i位置的数 的方案数+前i-1个数中数字和为j的方案数。

当i位置的数刚好等于j时,方案数会增加一。

当i位置的数大于j时,显然dp[i][j]=dp[i-1][j]

<
由于篇幅限制,无法直接列出100道经典题目及多种语言答案,不过可以给出一些示例,涵盖蓝桥杯、牛客网、力扣的部分经典题目及不同语言的解答。 ### 蓝桥杯 - 货物摆放 - **题目**:小蓝有一个超大的仓库,可以摆放很多货物。现在,小蓝有 $n$ 箱货物要摆放在仓库,每箱货物都是规则的正方体。小蓝规定了长、宽、高三个互相垂直的方向,每箱货物的边都必须严格平行于长、宽、高。小蓝希望所有的货物最终摆成一个大的长方体。即在长、宽、高的方向上分别堆 $L$、$W$、$H$ 的货物,满足 $n = L \times W \times H$。请问,一共有多少种堆放货物的方案满足要。例如,当 $n = 4$ 时,有以下 6 种方案:$1 \times 1 \times 4$、$1 \times 2 \times 2$、$1 \times 4 \times 1$、$2 \times 1 \times 2$、$2 \times 2 \times 1$、$4 \times 1 \times 1$。请问,当 $n = 2021041820210418$ (注意有 16 位数字)时,总共有多少种方案? - **Python 代码**: ```python n = 2021041820210418 factors = [] i = 1 while i * i <= n: if n % i == 0: factors.append(i) if i != n // i: factors.append(n // i) i += 1 count = 0 for l in factors: for w in factors: if n % (l * w) == 0: h = n // (l * w) count += 1 print(count) ``` ### 牛客网 - 反转链表 - **题目**:给定一个单链表的头结点 $pHead$ (该头节点是有值的,比如在下图,它的 val 是 1),长度为 $n$,反转该链表后,返回新链表的表头。 - **Python 代码**: ```python class ListNode: def __init__(self, x): self.val = x self.next = None def ReverseList(pHead): pre = None cur = pHead while cur: next_node = cur.next cur.next = pre pre = cur cur = next_node return pre ``` - **Java 代码**: ```java class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } } public class Solution { public ListNode ReverseList(ListNode head) { ListNode pre = null; ListNode cur = head; while (cur != null) { ListNode next = cur.next; cur.next = pre; pre = cur; cur = next; } return pre; } } ``` ### 力扣 - 两数之 - **题目**:给定一个整数数组 $nums$ 一个整数目标值 $target$,请你在该数组中找出为目标值 $target$ 的那两个整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案。 - **Python 代码**: ```python def twoSum(nums, target): num_dict = {} for i, num in enumerate(nums): complement = target - num if complement in num_dict: return [num_dict[complement], i] num_dict[num] = i ``` - **Java 代码**: ```java import java.util.HashMap; import java.util.Map; class Solution { public int[] twoSum(int[] nums, int target) { Map<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < nums.length; i++) { int complement = target - nums[i]; if (map.containsKey(complement)) { return new int[]{map.get(complement), i}; } map.put(nums[i], i); } return null; } } ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值