python实现:分别采用递归方法与动态规划算法实现“币值最大化问题”和“找零问题”。要求动态地调整两个问题的规模,记录程序运行时间。绘制曲线图比较在相同规模n情况下采用递归方式和动态规划实现的效率
动态规划算法实现币值最大化问题: 传入列表list。创建一个描述最大币值的列表C。在列表C开头位置添加0。C第一个位置添加硬币第一个。从index=2开始到index=最后硬币的位置,循环。C列表每个index等于硬币列表list对应位置的值加上index-2位置(不连续的)的值和,与index-1(上一个位置)中的最大值。直到循环结束,C列表最后一个位置记录了,最大币值。
递归实现币值最大化问题: 不用新窗帘最大币值列表C,在币值列表list里直接更新数据。递归返回Index位置上的值,等于硬币列表list对应位置的值加上index-2位置(不连续的)的值和,与index-1(上一个位置)中的最大值。另一个返回值为当前位置。
动态规划算法实现找零问题: 传入硬币列表和需要找零的金额。如果硬币列表中有需找零金额,只需一个硬币即可,直接返回1。创建一个长度为需找零金额的大小。从1到此金额做循环。找到每个金额的最少硬币数。循环内循环查找,此金额减去每种硬币面值,那种情况所需硬币数最小。存入temp。最终返回。
递归实现找零问题: 同动态算法一样,硬币面值中含有需找零金额时,返回1。其余情况返回最小所需硬币数。
import time
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #正常显示中文标签
import random
list = [5,1,2,10,6,2] #币值最大化列表
D = [1,2,5,10]#为了方便设置 从小到大排序的列表 并缺硬币最小值为1。
#动态规划算法实现 币值最大化问题
def coin(list):
list.insert(0, 0)
C=[]
C.append(0)
C.append(list[1])
for _ in range(2,len(list)):
C.append(max((list[_]+C[_-2]),C[_-1]))
return C
#递归实现 币值最大化问题
def coin2(list,i):
if i == 0:
return 0
if i == 1:
return list[1]
return max((list[i]+coin2(list,i-2)),coin2(list,i-1))
#递归实现 零钱找零
def coins_change(coin_values, change):
min_count = change
if change in coin_values:
return 1
for value in [i for i in coin_values if i <= change]:
count = 1 + coins_change(coin_values, change-value)
if count < min_count:
min_count = count
return min_count
#print('需要硬币个数:',coins_change(D,32))
#动态规划实现 零钱找零
def ChangeMaking(coin_values, change):
if change in coin_values:
return 1
F = []
F.append(0)
for _ in range(1,change+1): #创建一个长度为change的列表
F.append(0)
for i in range(1,change+1):
temp = 999
j = 1
while(j <= len(coin_values) and i >= coin_values[j-1]):
temp = min(F[i - coin_values[j-1]], temp)
j += 1
F[i] = temp +1
return F[i]
#print('需要硬币个数:',ChangeMaking(D,32))
#硬币最大化 动态输入硬币列表
'''
list = []
lei = int(input(" 请输入硬币种类数:"))
print("输入硬币种类:")
for _ in range(0,lei):
list.append(int(input()))
print('硬币为:',list)
print('动态算法不相邻硬币最大化:',coin(list).pop())
# list.insert(0,0) #若也要运行coin(),则注销这行; 若只运行coin2,则不注销
print('递归算法不相邻硬币最大化:',coin2(list,6))
'''
#找零问题
'''
D = []
lei = int(input(" 请输入硬币种类数:"))
print("输入硬币种类(包含币值为1):")
for _ in range(0,lei):
D.append(int(input()))
D.sort()
print('硬币为:',D)
money = int(input("输入需要找零金额:"))
print('递归算法需要硬币个数:',coins_change(D,money))
print('动态算法需要硬币个数:',ChangeMaking(D,money))
'''
#硬币最大化 折线图对比动态规划和递归
'''
start_coin = []
end_coin = []
start_coin2 = []
end_coin2 = []
x = []
y_coin = []
y_coin2 = []
for _ in range(0,10):
print(_+1)
list = []
lei = int(input(" 请输入硬币种类数:"))
x.append(lei)
for i in range(0, lei):
list.append(random.randint(1,10))
print('硬币为:', list)
start_coin.append(time.time())
print(coin(list).pop())
end_coin.append(time.time())
start_coin2.append(time.time())
print(coin2(list,lei))
end_coin2.append(time.time())
for _ in range(0, len(start_coin)):
print((end_coin[_]-start_coin[_])*100000)
y_coin.append((end_coin[_]-start_coin[_])*100000)
for _ in range(0, len(start_coin)):
print((end_coin2[_]-start_coin2[_])*100000)
y_coin2.append((end_coin2[_]-start_coin2[_])*100000)
plt.plot(x, y_coin, label='coin', linewidth=1, color='r', marker='o', markerfacecolor='blue', markersize=8)
plt.plot(x, y_coin2, label='coin2', linewidth=1, color='b', marker='o', markerfacecolor='blue', markersize=8)
plt.xlabel('num')
plt.ylabel('time')
plt.title('visible')
plt.legend()
plt.show()
'''
#找零问题 折线图对比动态规划和递归
start_Recursive = []
end_Recursive = []
start_dynamic = []
end_dynamic = []
x = []
y_Recursive = []
y_dynamic = []
D = []
D = [1, 2, 3, 5, 10]
D.sort()
for _ in range(0,10):
print('\n','第',_+1,'次循环')
print('硬币为:', D)
money = int(input("输入需要找零金额:"))
x.append(money)
start_Recursive.append(time.time())
print(coins_change(D,money))
end_Recursive.append(time.time())
start_dynamic.append(time.time())
print(ChangeMaking(D,money))
end_dynamic.append(time.time())
for _ in range(0, len(start_Recursive)):
print((end_Recursive[_]-start_Recursive[_])*100000)
y_Recursive.append((end_Recursive[_]-start_Recursive[_])*100000)
for _ in range(0, len(start_dynamic)):
print((end_dynamic[_]-start_dynamic[_])*100000)
y_dynamic.append((end_dynamic[_]-start_dynamic[_])*100000)
plt.plot(x, y_Recursive, label='Recursive', linewidth=1, color='r', marker='o', markerfacecolor='blue', markersize=8)
plt.plot(x, y_dynamic, label='dynamic', linewidth=1, color='b', marker='o', markerfacecolor='blue', markersize=8)
plt.xlabel('num')
plt.ylabel('time')
plt.title('visible')
plt.legend()
plt.show()
- 编写查找一个单链表特定元素的程序。分别使用递归和非递归方法实现,并比较它们的运行时间。
- 分别使用递归方法和非递归方法求斐波那契数列,并比较两者的运行速度(测量代码运行时间)
- 4.第三单元任务三实训:编写一个类ExceptionTest,在main方法中使用try-catch-finally语句结构实现:在try语句块中,编写两个数相除操作,相除的两个操作数要求程序运行时用
- python记录程序运行时间的几种方法
- 三种计算Python的代码块或程序的运行时间的方法比较
- python记录程序运行时间的三种方法
- 两种用c语言解决亲密数问题的方法并比较程序运行时间
- python记录程序运行时间的三种方法
- 求两个数字的最大公约数-Python实现,三种方法效率比较,包含质数打印质数的方法
- 练习2-1 编写一个程序一确定分别由signed及unsigned限定的char,short,int及long类型变量的取值范围。采用打印标准头文件中的相应值以及直接计算两种方式实现。通过直接计算来确定浮点类型的取值范围是一项难度很大的任务。
- 检测Python程序运行时间和内存占用的方法
- 关于c#中强制退出程序运行的两个方法比较
- java的list几种实现方式的效率(ArrayList、LinkedList、Vector、Stack),以及 java时间戳的三种获取方式比较
- 分析python程序运行时间的几种方法
- Python几种建表方法运行时间的比较
- VC程序采用动态链接库方式且静态链接MFC方法
- 关于Calendar类的compareTo方法比较两个时间不相等的问题
- 要求顺序循环队不损失一个空间,全部能够得到有效利用,试采用设置标志位tag的方法解决“假溢出”问题,实现顺序循环队列算法
- 从头认识Spring-3.6 简单的AOP日志实现(注解版)-需要记录方法的运行时间
- C++ 记录程序运行时间的方法总结