《算法问题实战策略》-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-数值分析的主要内容,如果未能解决你的问题,请参考以下文章

《算法问题实战策略》-chaper14-整数论

《算法问题实战策略》-chaper32-网络流

《算法实战策略》-chaper19-队列栈和双端队列

《算法问题实战策略》-chaper21-树的实现和遍历

《算法问题实战策略》 BOGGLE

JVM(二) GC算法与分代回收策略