导航:首页 > 源码编译 > 换硬币算法递归

换硬币算法递归

发布时间:2024-04-27 11:42:00

Ⅰ c璇瑷鎶10鍏幂‖甯佹崲鎴愪簲瑙掍竴瑙掍竴鍏幂殑鍙埚氩皯绉嶆崲鍙

涓浜哄缓璁锛氢粠澶у埌灏忛愭ョ粏鍒嗭纴棣栧厛镐诲拰10鍏冿纴鍙鍒嗘垚10涓涓鍏冿纴浠庝腑𨰾垮嚭涓涓涓鍏冨垎鎴愪袱涓浜旇掞纴铹跺悗浠庝袱涓浜旇掍腑𨰾垮嚭涓涓浜旇掑垎鎴愪簲涓涓瑙掞纴浠ユょ被鎺ㄩ愭ョ粏鍒嗭绂
鍏抽敭镄勫氨鏄1鍏=2*浜旇掞绂浜旇=5*涓瑙掞纴姣忎笅鍒嗕竴娆″氨璁╂柟娉曞姞1钬︹
void main()
{
int a=10,b=0,c=0,way=1;
for(a=10;a>=0;a--)
{
for(b=2*(10-a);b>=0;b--)
{
c+=5;
way++;
}
}
printf("%d\n",way);
}

python之动态规划算法

动态规划算法中是将复杂问题递归分解为子问题,通过解决这些子问题来解决复杂问题。与递归算法相比,动态编程减少了堆栈的使用,避免了重复的计算,效率得到显着提升。

先来看一个简单的例子,斐波那契数列.

斐波那契数列的定义如下。

斐波那契数列可以很容易地用递归算法实现:

上述代码,随着n的增加,计算量呈指数级增长,算法的时间复杂度是 。

采用动态规划算法,通过自下而上的计算数列的值,可以使算法复杂度减小到 ,代码如下。

下面我们再看一个复杂一些的例子。

这是小学奥数常见的硬币问题: 已知有1分,2分,5分三种硬币数量不限,用这些硬币凑成为n分钱,那么一共有多少种组合方法。

我们将硬币的种类用列表 coins 定义;
将问题定义为一个二维数组 dp,dp[amt][j] 是使用 coins 中前 j+1 种硬币( coins[0:j+1] )凑成总价amt的组合数。

例如: coins = [1,2,5]

dp[5][1] 就是使用前两种硬币 [1,2] 凑成总和为5的组合数。

对于所有的 dp[0][j] 来说,凑成总价为0的情况只有一种,就是所有的硬币数量都为0。所以对于在有效范围内任意的j,都有 dp[0][j] 为1。

对于 dp[amt][j] 的计算,也就是使用 coins[0:j+1] 硬币总价amt的组合数,包含两种情况计算:

1.当使用第j个硬币时,有 dp[amt-coins[j]][j] 种情况,即amt减去第j个硬币币值,使用前j+1种硬币的组合数;

2.当不使用第j个硬币时,有 dp[amt][j-1] 种情况,即使用前j种硬币凑成amt的组合数;

所以: dp[amt][j] = dp[amt - coins[j]][j]+dp[amt][j-1]

我们最终得到的结果是:dp[amount][-1]

上述分析省略了一些边界情况。

有了上述的分析,代码实现就比较简单了。

动态规划算法代码简洁,执行效率高。但是与递归算法相比,需要仔细考虑如何分解问题,动态规划代码与递归调用相比,较难理解。

我把递归算法实现的代码也附在下面。有兴趣的朋友可以比较一下两种算法的时间复杂度有多大差别。

上述代码在Python 3.7运行通过。

Ⅲ python n个硬币中找一个假币,且已知假币较轻,怎么用递归和非递归两种方法求

思路:假设有数组arr,里面的int值代表银币重量,下标代表第几个银币。

循环(非递归):把数组第一个值赋值给变量tmp,从第二个变量循环到最后一个,比较循环里的变量和tmp值,如果不等,就返回小数下标。

递归:用二分思想,银币分2堆(不能均分时把中间那个留出来),取重量小的那堆继续二分。最后只剩下一个时就是所求

下面这种写法是返回下标的。也可以把硬币假设成一种数据类型,然后返回那个类型

#!/usr/bin/python
#-*-coding:utf-8-*-

#返回最小值下标
defgetMin(arr1):
iflen(arr1)==0:return-1

tmp=arr1[0]
index=0
forcurinarr1:
iftmp!=cur:
return0iftmp<curelseindex
index+=1
return-1

real_index=0
#返回最小值下标递归
defgetMinRecursion(arr1):
globalreal_index
n=len(arr1)
ifn==0:return-1

ifn==1:returnreal_index
ifn==2:returnreal_indexifarr1[0]<arr1[1]elsereal_index+1

sum1=sum(arr1[0:int(n/3)])
sum2=sum(arr1[int(n/3):int(n/3)*2])

ifsum1==sum2:
real_index+=int(n/3)*2
returngetMinRecursion(arr1[int(n/3)*2:n+1])
ifsum1<sum2:
returngetMinRecursion(arr1[0:int(n/3)])
else:
real_index+=int(n/3)
returngetMinRecursion(arr1[int(n/3):int(n/3)*2])

arr=[1,1,1,1,1,1,0,1,1]
print("%d"%getMin(arr))
print("%d"%getMinRecursion(arr))

Ⅳ c璇瑷缂栫▼鐢ㄤ竴鍏冧簲瑙掍汉姘戝竵鍏戞崲浜斿垎涓ゅ垎鍜屼竴鍒嗙殑纭甯侊纴姣忎竴绉嶆柟妗堢‖甯佹绘暟涓嶈兘瓒呰繃涓锏炬灇锛岄梾鍑犵嶅厬鎹㈡柟妗

13绉嶃
1銆佹湁涓夌嶅舰寮忕殑C + +璇瑷鏁存暟甯告暟锛鍗佽繘鍒锛屽叓鍜鍗佸叚杩涘埗銆
锛1锛夊崄杩涘埗鏁存暟鏄鐢辨暟瀛0镊9镄勬暟鎹涓崭互0寮濮嬨
锛2锛鍏杩涘埗鏁存暟鏄鏁板瓧0锝7浠0寮濮嬬殑鏋勬垚镄勬暟鎹銆
锛3锛夊崄鍏杩涘埗鏁存暟鏄浠0鍙风殑缁勬垚镄9涓鏁版嵁寮濮嬩互0x鎴0X鍜屽瓧姣崭粠a鍒癴锛埚ぇ鍐椤拰灏忓啓瀛楁瘝锛夈
2銆佽緭鍏ユ槸涓涓姝f暣鏁n锛屾寚绀虹涓N涓鍙鑳界殑鏂规堥渶瑕佽緭鍑恒傝ユ柟妗堢殑椤哄簭鏄浠庡皯鍒板氱殑鎸変簲缇庡垎纭甯併
3銆佽緭鍑烘牸寮忥细
鏄剧ず镄5缇庡垎锛2缇庡垎锛1缇庡垎锛岀涓n鏂规堢殑鏁伴噺銆傛疮琛屾樉绀轰竴涓鏂规堬纴鐢锛屾渶钖庝竴涓鏁板瓧钖庨溃娌℃湁绌烘牸镄勬暟瀛椾箣闂存湁涓涓绌烘牸銆
娉锛氩傛灉链夊皬浜峦镄勬柟妗堬纴镓链夊彲鑳界殑鏂规埚皢渚濇¤緭鍑恒
𨰾揿𪾢璧勬枡;
1銆丆璇瑷鏄涓绉嶉溃钖戣繃绋嬬殑锛屾娊璞$殑涓鑸镄缂栫▼璇瑷锛屽畠琚骞挎硾搴旂敤浜庡簳鍙戝𪾢銆 C璇瑷缂栬疟鍜屼互绠鍗旷殑鏂瑰纺澶勭悊浣庣骇鍒镄勫唴瀛樸 C璇瑷鏄浜х敓浠链哄櫒璇瑷灏戦噺骞跺彲浠ュ湪娌℃湁浠讳綍琛岄┒鐜澧冩敮鎸佽繍琛岀殑链夋晥缂栫▼璇瑷銆傝槠铹禖璇瑷鎻愪緵浜呜稿氢绠绾у埆镄勫勭悊锷熻兘锛屼絾瀹冧粛铹朵缭鎸佷简璺ㄥ钩鍙扮殑鐗规с傚啓鍦ㄦ爣鍑呜勬牸镄凛璇瑷绋嫔簭涔熷彲浠ュ湪璁稿氲$畻链哄钩鍙帮纴鍖呮嫭涓浜涙搷浣滃钩鍙帮纴濡傚祵鍏ュ纺澶勭悊鍣ㄥ拰瓒呯骇璁$畻链杩涜岀紪璇戙
2銆佺幇鍦ㄦ渶鏂扮殑C璇瑷镙囧嗳鏄疌18銆
3銆丆璇瑷鏄涓绉嶉溃钖戣繃绋嬬殑璁$畻链虹▼搴忚捐¤瑷锛屽叾鏄浠庨溃钖戝硅薄镄勭紪绋嬭瑷锛屽侰 ++锛孞ava鍜岀瓑涓嶅悓銆 C璇瑷镄勮捐$洰镙囨槸鎻愪緵涓绉岖紪绋嬭瑷锛屽彲浠ヤ互绠鍗旷殑鏂瑰纺缂栬疟鍜屽伐镩轰绠绾у埆镄勫唴瀛桡纴鍙鐢熶骇链哄櫒浠g爜骞惰繍琛屼竴涓灏忕殑閲忔病链変换浣曡繍琛岀幆澧幂殑鏀鎸併
4銆 C璇瑷鎻忚堪镄勯梾棰桦揩浜姹囩紪璇瑷锛屼互杈冨皯镄勫伐浣滈噺锛岃坛濂界殑鍙璇绘э纴瀹规槗璋冭瘯锛屼慨鏀瑰拰绉绘嶏纴鍜屼唬镰佽川閲忕瓑钖屼簬姹囩紪璇瑷銆 C璇瑷涓鑸鍙链10锛咃綖20锛咃纴姣旂敱姹囩紪璇瑷浠g爜镓浜х敓镄勭洰镙囩▼搴忕殑鏁堢巼浣庛傚洜姝わ纴C璇瑷鍙浠ラ氲繃缂栧啓绯荤粺杞浠躲
5銆丆璇瑷鏄涓绉嶉溃钖戣繃绋嬬殑缂栬疟璇瑷銆傚叾杩愯岄熷害鏄闱炲父蹇镄勶纴浠呮′簬姹囩紪璇瑷銆 C璇瑷鏄璁$畻链轰骇涓氱殑镙稿绩璇瑷銆傛搷浣灭郴缁燂纴纭浠堕┍锷ㄧ▼搴忥纴鍏抽敭閮ㄤ欢鍜屾暟鎹搴撴槸浠嶤璇瑷涓嶅彲鍒嗙;濡傛灉涓嶅︿範C璇瑷锛屼綘鍙浠ヤ笉鐞呜В搴曞眰镄勮$畻链恒

Ⅳ 硬币兑换问题回溯法伪代码

A数组用来存放硬币,数值1代表正面,0代表反面;
static int s;s是存放每列状态的数初始为0代表一列都没翻,第几位为1就代表第几列被翻转
int turncoin(A,S,N,n) //A(N*9数组) ,N是行数 n代表当次翻哪一列 初次调用n=0,代表第一列
{ int i=1;//因为每列只有两种状态,所以每列只翻一次
static int max=0;//用来存放翻转后正面朝上的最大硬币数;
static int S;//大S用来存储当前硬币堆的翻转状态
do {turncoin(A,S,N,n+1);if (n==8){ int tem=sum //sum为遍历A数组,所有元素之和(即为当前正面朝上的硬币数)
if(sum>max){S=s; //把当前翻转状态存储到S,S内总是存储着拥有正面朝上硬币数量最高的一种翻转状态;}}}while(i--&&transform(N,n));
//transform()函数翻转第N列的硬币 并且对s的第n位置一 成功返回ture 并且对是 实现就是for(i=0;
ireturn S; //好了 这里S根据S每一位就得道最终所要求的结果}
拓展资料:
一、题目描述:
一个翻硬币的游戏,有N(N <=10000)行硬币,每行有九个硬币,排成一个N*9的方阵,有的硬币正面朝上,有的反面朝上。我们每次可把一整行或者一整列的所有硬币翻过来,请问怎么翻,使得正面朝上的硬币尽量多(翻硬币无次数限制)。
二、思路分析:
枚举2^9种列的翻法。
遍历N行,如果某行正面朝上的少,翻之;如果正面朝上的多,不翻
记下使得正面最多的方法即可
耗时O(2^9 * N)
这个得到的是最优解.用位运算效率还是很高的.
对每一列,都用一个9位的数表示,一共有N个
然后便利所有的9位状态,(000000000)-(111111111) (二进制)
对于每个状态,都与这N个数异或,每次异或后累加所有的1的值假设为k,如果k小于5则k=9-k.
对N个数累加所有的k,得到最终累加和.
求出所有状态下累加和最大的,就是正面朝上的硬币尽量多的个数.
翻面的方法横列分别是最优解的8位状态和与之对应的每个数异或后累加和k是否小于5.

阅读全文

与换硬币算法递归相关的资料

热点内容
超短macd源码 浏览:163
群晖怎么设置用户访问指定文件夹 浏览:555
安卓怎么测触摸屏 浏览:593
javastring原理 浏览:315
如何关闭手机dhcp服务器 浏览:981
php免费ide 浏览:200
程序员词句 浏览:976
服务器如何禁止某个ip段 浏览:329
便签手机文件夹 浏览:768
gameloft的java游戏 浏览:110
神佑释放怎么转服务器 浏览:735
洋葱app软件怎么登录 浏览:788
两相电空气压缩机 浏览:396
基于51单片机的智能语音密码锁设计 浏览:845
mac如何用ssh登录服务器 浏览:446
appstore怎么设置 浏览:954
在哪个app买韩国女装 浏览:111
php写入文件换行 浏览:749
dsp实现fft算法 浏览:485
棋牌源码转让交易手续费 浏览:293