递归解决方案的动态编程解决方案
Dynamic Programming solution for a Recursion solution
给定一个输入n
,求出所有可能的数字组合1 ... n
的和。例如,如果n=3
,那么所有可能的组合都是
(1),(2),(3),(1,2),(1,3),(2,3),(1,2,3)
它们的总和是
1 + 2 + 3 + (1+2) + (1+3) + (2+3) + (1+2+3) =24
我可以用recursion
来解决这个问题。如何使用Dynamic Programming
解决此问题?
#include<iostream>
using namespace std;
int sum=0,n;
int f(int pos,int s)
{
if(pos>n)
{
return 0;
}
else
{
for(int i=pos+1;i<=n;++i)
{
sum+=s+i;
f(i,s+i);
}
}
}
int main()
{
cin>>n;
sum=0;
f(0,0);
cout<<sum<<'n';
}
}
编辑尽管这个问题可以用这个级数在恒定时间内解决。
但我想知道如何使用Dynamic Programming
来实现这一点,因为我在这方面非常薄弱。
您不需要使用动态编程;如果你愿意,你可以用简单的算术。
案例数为2^n,因为对于给定的总和,每个数字都是开或关的。
从1到n的每一个数字都正好用在一半的和中,所以每个数字都是2^(n-1)次。1+2+…+n=(n-1)*n/2。
所以和是(n-1)*n/2*2^(n-1。对于n=3,它是(4*3/2)*4=24。
EDIT:如果您真的想使用动态编程,这里有一种方法。动态规划利用保存子问题的结果来加快超级问题的求解速度。在这个问题中,子问题是从1。。。n-1.
因此,从n->(组合的数量,组合的总和)创建一个映射。
使用1->(2,1)初始化。因为有两个组合{0,1},并且和为1。包括0只会让数学运算变得简单一点。
然后您的迭代步骤是使用映射。
假设(n-1)->(k,s),这意味着有k个集合对1求和。。。n-1.
则n的集合数为k*2(每个组合要么有n,要么没有)。所有组合的和是s+(s+k*n),因为你有上一个和(其中n缺失)加上所有有n的组合的和(应该比s多k*n,因为每个组合中有k个有n的新组合)。
所以加n->(2*k,2*s+k*n)。
你的最终答案是n->(k,s)中的s。
设dp[n]为结果,因此:
dp[1] = 1
dp[n] = 2 * dp[n-1] + 2^(n-1) * n
首先,很明显,dp[1]=1
其次,dp[n]是包含n的和和不包含n 的和
E.G:dp[3]={(1)(2)(1,2)}+{(3),(1,3),(2,3)
我们可以发现dp[n-1]出现两次,n的数量出现2^(n-1)次
我想也许这就是你想要的。
- 运行同一解决方案的另一个项目的项目
- Project Euler问题4的错误解决方案
- 计算每个节点的树高,帮助我解释这个代码解决方案
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- visual c++,如何获取解决方案目录中的代码
- 有没有办法在远程设备上打开和编辑visual Studio 2017解决方案
- C++Matching Brackets 2解决方案不起作用
- 在 ubuntu3 上C++ goto 定义有什么解决方案吗16.04?
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 我的固定时间步长与增量时间和插值的解决方案是错误的吗?
- 无法在问题解决方案中执行输出逻辑
- C++中TSP的动态编程解决方案
- 迭代解决方案作为动态编程
- 如何验证竞争性编程任务的动态编程解决方案的正确性
- 竞争性编程:解决方案运行速度太慢
- ::createFile winApi 失败,出现错误 5 (access_denied).是外壳编程或其他解决方案或任
- 用于编程练习(管件)的回溯解决方案
- 递归解决方案的动态编程解决方案
- 使用动态编程进行更改的所有解决方案
- 有效测试多个学生的编程解决方案