动态规划初步进阶(一)
来源:互联网 发布:linux ed2k 终端 编辑:程序博客网 时间:2024/06/05 14:53
如果我们有面值为1元、3元和5元的硬币若干枚,如何用最少的硬币凑够11元?
动态规划的思想:1.当我们遇到一个大问题时,总是习惯把问题的规模变小,这样便于分析讨论。 2.这个规模变小后的问题和原来的问题是同质的,除了规模变小,其它的都是一样的,本质上它还是同一个问题(规模变小后的问题其实是原问题的子问题.
动态规划的求解过程中有两个概念:状态和状态转移方程。状态就是如何描述这个问题并且如何求解的过程。在这个问题中。可以采用dp(i)=j来表示i元由j个硬币组成的。表示出了这个子问题过后,进行如何求解的过程。dp(0)=0表示0元由0个硬币组成,dp(1)=dp(1-1)+1,表示拿起一个面值为1的硬币,接下来只需要凑够0元即可,而这个是已经知道答案的,即d(0)=0。在大部分的动态规划中都有当前状态依赖于前一个状态,并且独立于后面的状态。要当前所求的值最小,只要满足前一个依赖的状态最小就可以达到要求。再接下来分析,dp(2)=dp(2-1)+1,因为还是只有1元硬币可以使用。所以只能取一个一元的硬币,凑够dp(1)就即可。在dp(3)时可以有两种取法。一种是dp(3)=dp(3-1)+1或者dp(3)=dp(3-3)+1.分别表示取一个一元硬币各先取3元硬币,就有两种值。从这些状态中我们可以推出状态转移方程:d(i)=min{ d(i-vj)+1 },其中i-vj >=0,vj表示第j个硬币的面值;有了状态转移方程,就可以很快解决这个问题。具体代码如下:
#include <iostream>using namespace std;int main(){ int num[100],V[3]={1,3,5};int N=11;int i,j;for(i=0;i<100;i++) ////进行数据初始化num[i]=1000;num[0]=0; ////问题起点for(i=1;i<=N;i++)////求得每一个dp{i]{for(j=0;j<3;j++) if(V[j]<=i && num[i-V[j]]+1 < num[i])///进行判断查找最大值num[i]=num[i-V[j]]+1; cout<<i<<":"<<num[i]<<endl; ///输出每种情况}cout<<num[N]<<endl;///输出最小硬币数目 return 0;}
附上运行结果示截图:
0 0
- 动态规划初步进阶(一)
- 动态规划初步
- 动态规划初步探索
- nyoj_853动态规划-初步
- 动态规划初步
- 动态规划初步
- 动态规划初步
- 动态规划初步
- 动态规划初步
- 动态规划初步
- 动态规划初步
- 动态规划初步
- 1D/1D动态规划优化初步 模型一
- 算法之动态规划初步认识(一)
- 动态规划进阶篇
- 动态规划进阶
- 动态规划-进阶
- 动态规划进阶
- ACM: 动态规划 poj 1190
- 给未来的你 — 李开复在2011…
- ACM: 动态规划 poj 1160 终于有点…
- ACM: 最长公共子序 poj 1458
- java-ThreadLocal是解决线程安全问题
- 动态规划初步进阶(一)
- ACM: 动态规划题 poj 1191 Nothing…
- ACM: 动态规划 poj 1390
- ACM: 动态规划 poj 1088
- ACM: 动态规划 poj 1579
- ACM: 动态规划 poj 1887
- ACM: poj 1050
- ACM: 动态规划 poj1695
- ACM: 暴力题 poj 1338