| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2070 人关注过本帖, 2 人收藏
标题:这个C程序谁能编出来啊?
只看楼主 加入收藏
chimeixing
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:14
专家分:130
注 册:2010-10-19
收藏
得分:0 
回复 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 元

菜鸟
2013-05-28 00:01
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
回复 21楼 chimeixing
呵呵,证明的不错。结果也是正确的,至于误差是由于双精度浮点型的有效位数限制造成的,允许。

兑现我的承诺,有时间去我的百分贴回复一下领分。同时送一段我的代码给你参考。

程序代码:
#include <stdio.h>
int main()
{
    double a[] = {1.0756, 1.1584, 1.2484, 1.45, 1.8064};
    double f[2048] = {2000}, t;
    int b[] = {1, 2, 3, 5, 8};
    int n, i, j;
    
    scanf("%d", &n);
    for(i = 1; i <= n; i++)
    for(j = 0; j < 5 && i - b[j] >= 0; j++)
        if(f[i] < (t = f[i - b[j]] * a[j])) f[i] = t;
    
    printf("%.2f", f[n]);
    
    return 0;
}

重剑无锋,大巧不工
2013-05-28 00:47
hsjjgm
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:106
专家分:189
注 册:2013-4-27
收藏
得分:0 
学习
2013-06-01 10:48
快速回复:这个C程序谁能编出来啊?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016374 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved