《算法问题实战策略》-chaper13-数值分析
Posted 黑大帅之家
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《算法问题实战策略》-chaper13-数值分析相关的知识,希望对你有一定的参考价值。
这一章节主要介绍我们在进行数值分析常用的二分、三分策略。
首先介绍二分。
其实二分的思想很好理解并且笔者在之前的一些文章中也有所渗透,对于二次函数甚至单元高次函数的零点求解、线段树还有《algorithm puzzle》当中的“切割钢条”问题,都是基于二分思想。
下面我们通过具体的问题来应用二分这种数值分析的策略。
Ex1:按揭贷款
以P%的年利率借贷N元后,在M个月内,以每月还C元的方式还贷。贷款期限内,按照如下形式计算贷款余额。
(1) 贷款余额从余额N元开始。
(2) 美国一个月,贷款余额会增加一个月的利息,月利率为(P/12)%。
(3) 增加利息后,从贷款余额中扣除当月的还款项。
分析:我们从较为抽象化的角度来建立一个数学模型,这道问题M,P,N,C等输入数据相当于是自变量,而还贷过程相当于是个函数机制,M月后的借贷余额便是因变量。
对于函数的这三要素,我们都是知道的,那么我们可以将问题转化成在满足因变量≤0的情况下,求解C的最小值。
如果我们想尝试利用数学方法,会发现我们虽然了解函数机制,但是我们难以列出其表达式,因此这里我们基于自变量C的解区间,进行二分搜索,而这个过程恰恰基于函数机制和因变量(函数余额)的范围限制。
简单的参考代码如下:
#include<cstdio> using namespace std; double balance(double amount , int duration , double rates , double monthlypayment)//求解每月还贷monthlypayment元,duration个月后的贷款余额。 { double balance = amount;//贷款余额初始化 for(int i = 0;i < duration;i++) { balance *= (1.0 + (rates/12.0)/100.0);//这里涉及简单的还贷机制,我们将其理解为每月底涨息后还贷 balance -= monthlypayment; } return balance; } double payment(double amount , int duration , double rates) { double l = 0;//每月还贷可行解的区间,基于这道问题的特殊情景(区间右端点一定可行,这与这个函数最后return的变量呼应),解区间分布情况是(,] double r = amount*(1.0 + (rates/12.0)/100.0); double mid; for(int i = 0;i < 100;i++) { mid = (r + l)/2.0; if(balance(amount , duration , rates , mid) <= 0) r = mid; else l = mid; } return r; } int main() { double amount , rates; int duration; printf("Input amount,rates and duration:"); scanf("%lf %lf %d",&amount,&rates,&duration); printf("the lowest monthlypayment: %llf",payment(amount,duration,rates)); }
以上是关于《算法问题实战策略》-chaper13-数值分析的主要内容,如果未能解决你的问题,请参考以下文章