问题描述
假设银行整存整取存款不同期限的月利率为:
0.63%
,期限为1年;0.66%
,期限为2年;0.69%
,期限为3年;0.75%
,期限为5年;0.84%
,期限为8年。
现在已知某人手上有2000
元,要求通过计算选择出一种存钱方案,使得这笔钱存入银行20年后获得的利息最多。假定银行对超出存款期限的那部分时间不付利息。
为了获取到最多的利息,应该在存入银行的钱到期后马上就取出来,然后再立刻将原来的本金加上当前所获取到的利息作为新的本金存入银行中,这样反复操作直到满20年为止。
又由于存款的期限不同,对应的利率是不相同的,因此在20年中,不同的存取期限的组合所获得的利息也是不相同的。
假设在这20年中,1年期限的存了x1次,2年期限的存了x2次,3年期限的存了x3次,5年期限的存了x5次,8年期限的存了x8次,则到期时存款人所得的本利合计为:
2000×(1+0.063)x1×(1+0.066)x2×(1+0.069)x3 ×(1+0.075)x5×(1+0.084)x8
①
由题意可知,显然8年期限的存款次数最多为两次,因此可得到下面对存款期限的限定条件:
0≤x8≤2
0≤x5≤(20-8×x8)/5
0≤x3≤(20-8×x8-5×x5)/3
0≤x2≤(20-8×x8-5×x5-3×x3)/2
x1=20-8×x8-5×x5-3×x3-2×x2且x1≥0
算法设计
根据式①及对存款期限的限定条件,可以使用for循环来穷举出所有可能的存款金额,从中找出最大的存款金额就是该问题的解。
因为限定条件已经确定了,因此for循环的循环次数也就确定了。
确定程序框架
程序流程图如下图所示。
完整代码
根据上面的分析,编写程序如下:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @author : liuhefei
# @desc: 存钱问题
if __name__=="__main__":
#在20年中,1年期限的存了x1次,2年期限的存了x2次,以此类推
max = 0.0
for x8 in range(0,3):
t5 = (20-8*x8)//5 #存款5年的最大次数
for x5 in range(0, t5+1):
t3 = (20-8*x8-5*x5)//3 #存款3年的最大次数
for x3 in range(0, t3+1):
t2 = (20-8*x8-5*x5-3*x3)//2
for x2 in range(0, t2+1):
x1 = 20-8*x8-5*x5-3*x3-2*x2 # 存款期限限定条件
# 判断条件
result = 2000* ((1+0.0063*12)**x1) * ((1+2*0.0066*12)**x2)
* ((1+3*0.0069*12)**x3) * ((1+5*0.0075*12)**x5) * ((1+8*0.0084*12)**x8)
# y1、y2、y3、y5、y8用于记录获利最多的存款方式
if result > max:
max = result
y1 = x1
y2 = x2
y3 = x3
y5 = x5
y8 = x8
# 输出结果
print("获得利息最多的存款方式为:");
print("8年期限的存了%d次" %y8);
print("5年期限的存了%d次" %y5);
print("3年期限的存了%d次" %y3);
print("2年期限的存了%d次" %y2);
print("1年期限的存了%d次" %y1);
print("存款人最终的获得的本利合计:%0.2f" %result);
**
表示幂运算,x**y
返回x的y次幂,即计算xy的值。例如,5**2
=25。- 使用括号
()
改变程序的优先级。Python
语言中,括号()
拥有最高优先级,可以强制表达式按照需要的顺序求值,括号中的表达式会优先执行,也可以利用括号使得表达式更加易读。
运行结果
在vscode下运行程序,结果如下图所示。从输出结果中可知,获利最多的存款方式为连续存4次5年期的存款,则满20年所得到的本金一共为8763.19
元。注意在程序中控制了输出结果的小数位数为两位。