算法设计与分析P3_4

上传人:xmg****18 文档编号:114683691 上传时间:2019-11-12 格式:DOC 页数:9 大小:64.37KB
返回 下载 相关 举报
算法设计与分析P3_4_第1页
第1页 / 共9页
算法设计与分析P3_4_第2页
第2页 / 共9页
算法设计与分析P3_4_第3页
第3页 / 共9页
算法设计与分析P3_4_第4页
第4页 / 共9页
算法设计与分析P3_4_第5页
第5页 / 共9页
点击查看更多>>
资源描述

《算法设计与分析P3_4》由会员分享,可在线阅读,更多相关《算法设计与分析P3_4(9页珍藏版)》请在金锄头文库上搜索。

1、. . . . .问题描述设有n种不同面值的硬币,各硬币的面值存于数组T1:n中。现要用这些面值的硬币来找钱,可以实用的各种面值的硬币个数不限。(1)当只用硬币面值T1,T2,Ti时,可找出钱数j的最少硬币个数记为C(i,j)。若只用这些硬币面值,找不出钱数j时,记C(i,j)=。 给出C(i,j)的递归表达式及其初始条件。其中,1in,1jL.(2)设计一个动态规划算法,对于1jL,计算出所有的C(n,j).算法只允许使用一个长度为L的数组。用L和n作为变量表示算法的时间复杂性。(3)在C(n,j),1=j=L,已计算出的情况下,设计一个贪心算法,对任意钱数m=L,给出用最少硬币找钱m的方法

2、。当C(n,m)时,算法的计算时间为O(n+C(n,m)。分析这个问题用动态规划来解,归结到动态规划上面就变成了无限背包问题。区别在于,现在我们需要求一个最少的硬币数而不是最大值。但是选择的情况也是相同的,即每次选择都可以选择任何一种硬币。 首先,找零钱问题具有最优子结构性质:兑换零钱问题的最优子结构表述:对于任意需要找的钱数j,一个利用Tn中的n个不同面值钱币进行兑换零钱的最佳方案为P(T(1),j),P(T(2),j),.,P(T(n),j),即此时的最少钱币个数C(n,j)=k=0nP(T(k),j)则P(T(2),j),.,P(T(n),j)一定是利用Tn中n个不同的面值钱币对钱数j=

3、j-P(T(1),j)* T(1)进行兑换零钱的最佳方案。其次,找零钱问题具有重叠于问题性质:a)当n=1时,即只能用一种钱币兑换零钱,钱币的面值为T0,有 (2)根据分析建立正确的递归关系:复杂度:算法的时间复杂度主要取决于程序的两个循环,所以算法的时间复杂度为:O(n2);算法执行过程中引入了一个二维数组,随着输入规模的增大,所需要的空间复杂度为:O(n2)算法: #include #include using namespace std; #define MAX 20002 #define INF 9999999 #define min(a,b) (a)(b)?(b):(a) int T

4、11,Coins11,n;/硬币面值数组T,可以使用的各种面值的硬币个数数组 Coins,n种不同面值的硬币 int cMAX;/数组c存放要找的最少硬币个数 int m; /要找的钱数m void init() int i; coutn; coutn输入硬币面值及其此面值硬币的个数:endl; for(i=0;iTiCoinsi; coutm; int main(int argc, char *argv) init(); for(int i=0;i=m;+i) ci=INF; c0=0; for(int i=0;in;+i) for(int j=1;j=Ti;-k) ck=min(ck,ck

5、-Ti+1); if(cm!=INF) coutn最少硬币个数为:cmendl; else cout-1endl; return 0; 运行结果:时间复杂度:从上面算法可知,最优值cj的计算过程中,最外层为循环for(j=1;j1&flag=0)循环,而while(k1&flag=0)循环中又嵌套着三个并列的for循环。因此本算法最坏情况下的复杂度是O(L*2n);最好的情况当然是里面for循环的条件不满足而不执行,此时的复杂度为O(L*n)。其中:L表示需要兑换的零钱数,对于L来说,该值一般不是很大,对于钱币来说,L会小于100元,即10000分;n表示钱币的种类,n值一般不会很大如钱币总的

6、有13种(从1分,2分,100元)。经过以上分析,如是最坏情况时的复杂度应为O(L*2n),则该值对于内存和运行速度较小的自动售货机等的应用前景则不会很好。但本算法中的递归结构在LTn时,有可见对于钱币j=L时,求c(n,j)时,并不要求对从1ij,的所有情况都要求c(n,i)+1,而是只求。其中:1kn。钱币一般只有13种左右,因此其效率大为上升。最坏的情况下需要执行而M小于100元即10000分,远大于n。本算法的动态规划算法的时间复杂性比该问题的一般动态规划算法的效率要好得多。该算法的时间复杂性是103数量级的对于应用于自动售货机等运行速度较慢的机器来说是不成问题的。贪心算法由贪心算法可

7、知尽量用大面值的硬币组合来找钱,可以使使用的硬币最少。而贪心算法对最少硬币问题的解决总是可以得到最优解很好的近似解。例如:9分面值的硬币5枚,8分面值的硬币5枚,2分面值的硬币8枚,要找25分钱。设要找的钱为m,硬币种类为n,ti(0i=n)为硬币的面值,ci为可以使用的各种面值的硬币个数,ki为第i种面值的硬币可以使用的最多个数(ki=minm/ti,ci)(1)将硬币依面值大小排序982(2)按面值种类划分不同情况有多少种面值就划分多少种情况.每种情况的第一枚硬币面值各不一样,其后对剩余的硬币按面值从大到小排列.划分为三个情况:982,892,298。对应ki为:k0=3,k1=3,k2=

8、8得到近似最优解群为9分1枚,8分2枚;9分1枚,8分1枚,2分4枚;9分1枚,2分8枚.算法优化1,在寻找最优组合过程中,有些情况可以不予考虑。比如上例中2982,在以小面值的硬币为第一个的情况中,在寻找最优组合时,会遇到两种情况:a、使用硬币个数要比以大面值的硬币(如9和8)为第一个的情况大得多。b、寻找到的组合与前面的情况有重复。完整程序代码如下:#include#include#includeintn,money;structctypeintvalue;intcoin;templatevoidmake2Darray(type*&x,introws,intcols)x=newtype*r

9、ows;for(inti=0;irows;i+)xi=newtypecols;voidswap(ctype&a,ctype&b)ctypetemp;temp=a;a=b;b=temp;intpartition(ctypearray,intp,intr)inti,j;ctypekey;i=p;j=r+1;key=arrayp;while(true)while(array+i.valuekey.value);if(i=j)break;swap(arrayi,arrayj);arrayp=arrayj;arrayj=key;returnj;voidquicksort(ctypearray,intp,

10、intr)intq;if(pn;int*coins=newintn+1;ctype*T=newctypen+1;for(inti=1;iTi.value;inputTi.coin;inputmoney;quicksort(T,1,n);/*for(i=1;i=n;i+)coinsi=Ti.coin;*/intmax=0;for(i=1;i=n;i+) max+=Ti.coin;max+=10;int*min=newintmoney+1;min0=0;int*cnum;make2Darray(cnum,money+1,n+1);for(i=0;i=money;i+)for(intj=1;j=n;

11、j+)cnumij=0;if(T1.value=1)min1=1;cnum11=1;elsemin1=max;intj=2;while(j=money)minj=max;i=1;while(i=Ti.value) intcoinumber=cnumj-Ti.valuei;coinumber+;if(minj1+minj-Ti.value)&(coinumber=Ti.coin) for(intk=1;k=n;k+)cnumjk=cnumj-Ti.valuek; cnumji+; minj=1+minj-Ti.value;i+; j+;if(minmoney!=max)outputminmoney;elseoutput-1;宁可累死在路上,也不能闲死在家里!宁可去碰壁,也不能面壁。是狼就要练好牙,是羊就要练好腿。什么是奋斗?奋斗就是

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 大杂烩/其它

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号