377. 组合总和 Ⅳ
给你一个由 不同 整数组成的数组 nums
,和一个目标整数 target
。请你从 nums
中找出并返回总和为 target
的元素组合的个数。
题目数据保证答案符合 32
位整数范围。
数据范围
1 <= nums.length <= 200
1 <= nums[i] <= 1000
nums
中的所有元素 互不相同1 <= target <= 1000
分析
令dp[i]
表示总和为i
的方案数
- d p [ i ] + = ∑ j = 1 n d p [ i − n u m s [ j ] ] dp[i]+=\sum_{j=1}^{n}dp[i-nums[j]] dp[i]+=∑j=1ndp[i−nums[j]]
代码
class Solution {
public:const static int N = 1005, M = 205;unsigned long long dp[N];unsigned long long combinationSum4(vector<int>& nums, int target) {int n = nums.size();dp[0] = 1;for(int i = 0; i <= target; i ++ ) {for(int j = 1; j <= n; j ++ ) {if(i >= nums[j - 1])dp[i] += dp[i - nums[j - 1]];}}return dp[target];}
};
2466. 统计构造好字符串的方案数
给你整数 zero
,one
,low
和 high
,我们从空字符串开始构造一个字符串,每一步执行下面操作中的一种:
将 '0'
在字符串末尾添加 zero
次。
将 '1'
在字符串末尾添加 one
次。
以上操作可以执行任意次。
如果通过以上过程得到一个 长度 在 low
和 high
之间(包含上下边界)的字符串,那么这个字符串我们称为 好 字符串。
请你返回满足以上要求的 不同 好字符串数目。由于答案可能很大,请将结果对 109 + 7
取余 后返回。
数据范围
1 <= low <= high <= 105
1 <= zero, one <= low
分析
和上题思路一样,都算是爬楼梯类型
代码
class Solution {
public:const static int N = 1e5 + 5, mod = (int)1e9 + 7;unsigned long long dp[N];unsigned long long countGoodStrings(int low, int high, int zero, int one) {dp[0] = 1;unsigned long long res = 0;for(int i = 1; i <= high; i ++ ) {if(i >= zero) dp[i] += dp[i - zero];if(i >= one) dp[i] += dp[i - one];if(i >= low) res += dp[i];dp[i] %= mod;res %= mod;}return res;}
};
2266. 统计打字方案数
题目链接
分析
爬楼梯变式,令dp[i]为长度为i的字符串可能的文字信息数
- d p [ i ] + = ∑ j = 1 l a s t n u m s d p [ i − j ] ,其中 l a s t n u m s 为与 n u m s [ i ] 相接的相同数字个数,例如 2333 第 4 个位置的 3 的 l a s t n u m s 为 3 dp[i]+=\sum_{j=1}^{lastnums}dp[i-j],其中lastnums为与nums[i]相接的相同数字个数,例如2333第4个位置的3的lastnums为3 dp[i]+=∑j=1lastnumsdp[i−j],其中lastnums为与nums[i]相接的相同数字个数,例如2333第4个位置的3的lastnums为3
代码
class Solution {
public:const static int N = 1e5 + 5, mod = (int)1e9 + 7;unsigned long long dp[N];int cnt[30];unsigned long long countTexts(string pressedKeys) {int n = pressedKeys.size();for(int i = 2; i <= 9; i ++ ) cnt[i] = 3;cnt[7] = cnt[9] = 4;int lastNums = 0;dp[0] = 1;int tlast = 0;for(int i = 1; i <= n; i ++ ) {if(i >= 2) {if(pressedKeys[i - 1] == pressedKeys[i - 2]) lastNums ++ ;else lastNums = 1;} else lastNums = 1;tlast = min(lastNums, cnt[pressedKeys[i - 1] - '0']);for(int j = 1; j <= tlast; j ++ ) {dp[i] += dp[i - j];dp[i] %= mod;}}return dp[n];}
};