algorithm - K sum的算法总结
问题描述
这是众所周知的Twelvefold way
:
https://en.wikipedia.org/wiki/Twelvefold_way
我们想在哪里找到以下方程的解数:
X1 + X2 + ... + XK = target
从给定的数组:
vector<int> vec(N);
我们可以假设 vec[i] > 0。有 3 种情况,例如
vec = {1,2,3}, target = 5, K = 3.
Xi可以重复,解决方案可以重复。
6 个解是 {1,2,2}, {2,1,2}, {2,2,1}, {1,1,3}, {1,3,1}, {3,1,1}
Xi可以重复,解不能重复。
2 个解决方案是 {1,2,2}, {1,1,3}
Xi不能重复,解不能重复。
0 解决方案。
ide 必须使用动态编程:
dp[i][k], the number of solution of target = i, K = k.
迭代关系为:
if(i > num[n-1]) dp[i][k] += dp[i-num[n-1]][k-1];
对于三种情况,它们取决于 i,n,k 的运行顺序。当没有 K (任意数量的变量之和)限制时,我知道结果:
情况1:
int KSum(vector<int>& vec, int target) {
vector<int> dp(target + 1);
dp[0] = 1;
for (int i = 1; i <= target; ++i)
for (int n = 0; n < vec.size(); n++)
if (i >= vec[n]) dp[i] += dp[i - vec[n]];
return dp.back();
}
案例2:
for (int n = 0; n < vec.size(); n++)
for (int i = 1; i <= target; ++i)
案例3:
for (int n = 0; n < vec.size(); n++)
for (int i = target; i >= 1; --i)
当有额外的变量 k 时,我们只是简单地添加 for 循环
for(int k = 1; k <= K; k++)
在最外层?
编辑:
我尝试了案例1,只需在最里面添加K的for循环:
int KSum(vector<int> vec, int target, int K) {
vector<vector<int>> dp(K+1,vector<int>(target + 1,0));
dp[0][0] = 1;
for (int n = 0; n < vec.size(); n++)
for (int i = 1; i <= target; ++i)
for (int k = 1; k <= K; k++)
{
if (i >= vec[n]) dp[k][i] += dp[k - 1][i - vec[n]];
}
return dp[K][target];
}
case 2 和 case 3 是这样吗?</p>
解决方案
在没有变量的解决方案中K
dp[i] 表示有多少解决方案可以实现 sum i
。
包含变量K
意味着我们为子问题添加了另一个维度。此维度不一定必须位于特定轴上。您的dp
数组可能看起来像dp[i][k]
或dp[k][i]
。
dp[i][k]
表示i
使用k
数字(重复或唯一)累积和的解决方案的数量dp[k][i]
意味着使用k
数字多少个解决方案来累积总和i
两者都是一样的东西。这意味着您可以在外部或内部添加循环。
推荐阅读
- java - 无法在 Tomcat7 上运行 Spring Boot 2.0:“由于缺少 ServletWebServerFactory bean,无法启动 ServletWebServerApplicationContext。”
- python - pygame组更新方法不起作用
- aem - 在 AEM 中解密时出现 CryptoException
- angular - mat-menu的样式不能使用角度材料和flex css以角度工作
- apache - 使用 RewriteRule 隐藏部分 URL
- r - 将第一行(列标题)写入向量
- python - 进行 pip install 时我应该将项目资源放在哪里?
- r - 变量对象名称的 $ 运算符
- asp.net - 连续查找 10 位数字,将它们格式化为电话号码 ASP.NET
- r - R读取文件,操作文件名和从/向文件夹写入文件