之前动态规划在脑子里的概念总是模模糊糊的,这两天把思路梳理一下,整理成文。
动态规划概念略,还是直接用例子描述比较易懂。
排列组合问题
计算N个元素任取K个的选取所有可能数C(N,K)
在排列组合里面,我们有下面的式子:
当N>K>0,C(N,K) = C (N-1,K-1)+ C(N-1,K)
示意图如下:
所以,递归式就可以写作:f(n,k) = f(n-1,k-1) + f(n-1,k);
以下是代码:
int comb(int n,int k)
{
if(k>n)
{
printf("error data\n");
exit(1);
}
else
{
if(n == k || k == 0)
{
return 1;
}
else if(k == 1)
{
return n;
}
else
{
return comb(n-1,k-1) + comb(n-1,k);
}
}
}
01背包问题
问题描述:给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为C。问应如何选择装入背包的物品,使得装入背包中物品的总价值最大?
对于一种物品,要么装入背包,要么不装。所以对于一种物品的装入状态可以取0和1.我们设物品i的装入状态为xi,xi∈ (0,1),此问题称为0-11背包问题。
数据:物品个数n=5,物品重量w[n]={0,2,2,6,5,4},物品价值V[n]={0,6,3,5,4,6}
如图所示,v代表价值,w代表重量,num代表编号,表格上面的数字代表当前的空间数(s)。
当wi>s时,该物品无法放入背包。反之,可以放入背包。
从最后一个开始尝试放入背包:
继续第四个物品:因为在s=4开始价值不如最后一个,所以背包中放的依然是最后一个
然后是第三个,此时当s=10时,num3的价值大于了num4的价值,所以发生了取代。
然后依次是第二个,第一个,最后得到的最优解如下图:
用m(i,s)表示能得装进背包的最大价值,则根据前面的分析我们得到递推式:
i:物品号码;
s:物品重量
上图有一处错误,Max中,逗号后面应为:m(i+1,s-w[ i ])+v[ i ]