標籤:
此次部落格來自我選修課的一次作業,初學python, 我的程式難免有許多不合理的地方,希望大家指正。
問題描述:
每個月信用卡都會提示你還錢,至少要還的是你借款數額的2%。但是信用卡機構要收取未還清金額的利息,即使你及時還了要求償還的最少金額的錢,你仍舊要支付利息,利息要累積在仍欠的錢上面,也就是還沒有還款的一部分。
譬如,你用信用卡透支了5000美金,年利率是18%,每個月最少要還款2%,如果你每個月都是按照最小額度,也就是2%進行支付,1年之後還有多少錢沒還。
設計思想:
你可以這樣來考慮。
ub0=b0-p0
開始的第一個月記做0(這個時候信用卡狀態開始顯示欠款)。假設你的欠款是 b0(b代表需平賬目,角標0代表0月),你在這一個月裡要支付的金額由b,也就是需平賬目金額決定。第0個月還款p0,那你的欠款ub0 = b0 – p0(ub0代表你的欠款,也就是未平賬金額)。
b1=ub0+r/12.0*ub0
在“1”月開始,銀行會收取你所欠款金額的利息,如果你的年利率是r%,那麼你在“1”月開始,你的需平賬目金額為“0”月未支付金額和由這筆欠款產生的利息,即“1”需平賬目金額為 b1=ub0+r/12.0*ub0。
在“1”月,我們將再次進行付款p1,這次支付需包含部分利息。因此它不完全是原始金額,餘額ub1 = b1 – p1。
在“ 2”月開始的需平賬金額計算,可以由支付了p1之後計算未平金額,即餘額b2 = ub1 + r/12 * ub1。
1.編寫一個程式計算如果一個人每個月只支付銀行要求的最低還款金額,一年後該信用卡所欠餘額。
代碼實現:
balance=4213 #在此輸入欠款annualInterestRate=0.2 #年利率monthlyPaymentRate=0.04 #最少還款百分比print "balance=%d"%(balance)print "annualInterestRate=%.1f"%(annualInterestRate)print "monthlyPaymentRate=%.2f"%(monthlyPaymentRate)monthlyInterestRate=annualInterestRate/12total=0for i in range(12): MIN=monthlyPaymentRate*balance total+=MIN balance-=MIN balance=balance+balance*monthlyInterestRate print"Month:%d"%(i+1) print"Minimum monthly payment:%.2f"%(MIN) print"Remaining balance:%.2f"%(balance)print"Total paid:%.2f"%(total)print"Remaining balance:%.2f"%(balance)
2.寫一個程式實現12個月還清信用卡透支金額,計算出每月最少支付的固定金額,the number is fixed 固定的數值。
設計思想:
假定利息是月末累積,每個月支付金額的必須是10美金的倍數,(這種方案如果出現最後一個月支付出現欠額為負值,也是ok的,就是說如果按10美金每月支付固定金額,最後一個月可能出現多付錢的情況)。
範例程式:
def pay(balance,payment): for i in range(12): balance-=payment balance=balance+balance*monthlyInterestRate return balancebalance=3329 #測試時請修改此處annualInterestRate=0.2 #年利率monthlyInterestRate=annualInterestRate/12 #月利率print "balance=%d"%(balance)print "annualInterestRate=%.2f"%(annualInterestRate)payment=int(balance/12)/10*10while pay(balance,payment)>0: payment+=10print "Lowest Payment:%d"%(payment)
分析:
在2中,你每月支付必須是10整數倍。why?你可以試試在本地啟動並執行代碼,每月支付0.01美元的倍數,你的Program是否還能正常run?應該是可以的,但是你的Program會啟動並執行很慢,特別是當balance和rate很大的時候(就是資料計算量大的時候)。
對於Problem我們要怎麼才能算出才能使自己的程式時間效率O()好一點,當然是二分大法好!O(logn)的速度不是蓋的…..最簡單粗暴的就是從0-b0依次枚舉ans,O(n)的枚舉效率加一個迭代時間複雜度是O(n^2),二分是可以最佳化到總效率達到O(nlogn),可利用完全二叉樹的性質簡單證明,跟冒泡到歸併的最佳化是一樣的證明。簡單描述,二分ans可能出現的範圍這裡應該是[0,b0],利用二分的單調性,來不斷縮小搜尋區間,最後得到精確解。也就是減治法,每次減去一半的問題規模。
為解決這個問題,我們需要搜尋每月最小支付額度以保證我們在一年內能全部償還。那麼支付金額的合理下限是多少呢?$0是顯而易見的答案,但你可以做到更好。如果沒有利息產生,每月支付金額只需原始透支金額的十二分之一。因此我們必須每月最少支付這麼多,原始透支金額的十二分之一是個很好的下限。
那好的上限呢。假想我們不是每月支付,而是在年底一次性支付完整個金額,那麼我們最終支付必然大於我們將按月分期支付,因為產生了未支付金額的利息。因此一個好的每月支付上限是(透支價額加上一整年所附加的每月利息)/12。
改進程式:
def pay(balance,payment): for i in range(12): balance-=payment balance=balance+balance*monthlyInterestRate return balancebalance=320000 #測試時請修改此處annualInterestRate=0.2 #修改年利率monthlyInterestRate=annualInterestRate/12print "balance=%d"%(balance)print "annualInterestRate=%.2f"%(annualInterestRate) lower=balance/12upper=(balance*(1+annualInterestRate))/12payment=(lower+upper)/2while pay(balance,payment)<-0.01or pay(balance,payment)>0: if pay(balance,payment)<-0.01: upper=payment else: lower=payment payment=(lower+upper)/2 print "Lowest Payment:%.2f"%(payment)
註:以上程式均為自己編寫,初學python,許多功能不是很瞭解,只能用很繁瑣的形式來編寫。
一次二分法在python中的利用