回复 16楼 beyondyf
程序代码:#include<stdio.h>
#include<conio.h>
double dMoney[8] = {0}; /*储存0-7年 或者 n-7 到n年 的最大金额*/
int prevYear; /*记录当前金额是由几年前存入的*/
/*得到第n年的最大本金,计算公式为
Y(n) = max{ Y(n-1)*(1+a1*1) , Y(n-2)*(1+a2*2) , Y(n-3)*(1+a3*3) , Y(n-5)*(1+a5*5) , Y(n-8)*(1+a8*8)}
Y(n)表示第n年能够获得的最大金额 , 它只可能由 1年前存入,或者2年前存入,或者...或者8年前存入 ,
如果之前存入的确实是最大金额,由反证法可以证明 Y(n)也是第n年可以得到的最大金额
反证法:假设可以由另外一条途径获得更大的Y(n) , 由于最大的Y(n)必须由以上五个式子决定,
又由于以上五个式子的系数都是固定的,因此,必然存在更大的Y'(n-m)(m=1,2,3,5,8之一)
使得Y'(n-m) > Y(n-m) 这与假设:Y(n-m)是第n-m年获得的最大金额 相矛盾*/
double GetMaxMoney(int nYear);
/*n,nYear表示nYear年的时候,n年之前的本金,n=-1,-2,-3,-5,-8*/
double GetMoney(int n , int nYear);
int main()
{
int i , j ;
double dTmp;
dMoney[0] = 2000; /*初始状态为2000元,即第0年为2000元*/
for(i = 1 ; i <= 1000 ; i++)
{
dTmp = GetMaxMoney(i); /*由上面说到的公式计算第i年的最大金额*/
printf("从%d年前存入,%-4d 年是 %g\n" , prevYear , i, dTmp );
if(i < 8) /*i<8 表示前面8年没有填满,直接填写到对应位置*/
{
dMoney[i] = dTmp;
}
else /*i>=8 表示至少存了8年,则8年前的数据没用了,移除8年前的数据并添加新得到的数据*/
{
for(j = 0 ; j < 7 ; j++)
{
dMoney[j] = dMoney[j+1];
}
dMoney[7] = dTmp;
}
}
printf("%g" , dMoney[7]);
getch() ;
return 0;
}
double GetMaxMoney(int nYear) /*这里和上面的公式一一对应*/
{
double dMax = 0;
if(GetMoney(-1 , nYear) * (1+0.0063*12) > dMax)
{
prevYear = 1;
dMax = GetMoney(-1 , nYear) * (1+0.0063*12);
}
if(GetMoney(-2 , nYear) * (1+0.0066*12*2) > dMax)
{
prevYear = 2;
dMax = GetMoney(-2 , nYear) * (1+0.0066*12*2);
}
if(GetMoney(-3 , nYear) * (1+0.0069*12*3) > dMax)
{
prevYear = 3;
dMax = GetMoney(-3 , nYear) * (1+0.0069*12*3);
}
if(GetMoney(-5 , nYear) * (1+0.0075*12*5) > dMax)
{
prevYear = 5;
dMax = GetMoney(-5 , nYear) * (1+0.0075*12*5);
}
if(GetMoney(-8 , nYear) * (1+0.0084*12*8) > dMax)
{
prevYear = 8;
dMax = GetMoney(-8 , nYear) * (1+0.0084*12*8);
}
return dMax;
}
/*这里之所以要两个参数,是因为:nYear>8时只靠nYear无法确定返回哪个数据,只靠n又不能返回nYear<8时的数据*/
double GetMoney(int n , int nYear)
{
if(nYear < 8) /*年份小于8,只能靠两个参数一起确定返回的数据 */
{
if(nYear + n >= 0)
{
return dMoney[nYear + n];
}
return 0; /*年份为负需要返回0,想想为什么? */
}
return dMoney[8 + n]; /*nYear>8,直接n参数就可以确定数据 */
}
1000年结果为3.75518e35 元

菜鸟








