回复 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 元
菜鸟