QuXiao

每天进步一点点!

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  50 随笔 :: 0 文章 :: 27 评论 :: 0 Trackbacks

题目大意:

    给定一个时间期间n,电脑的价格c,以及电脑的维修费用m(y,z)(第y台电脑从y年用到第z年总的维修费用)。让你求出在期限n中使用电脑的最低费用。

思路:
    为了让总费用最低,你必须作出这样的决策:假设你正在使用某一台电脑已用到y年,你y+1年是继续用这台电脑,还是重新买第y+1台电脑(注意,这里的y+1是指输入中的第y+1行电脑,而不是指你已购买了y+1台电脑,因为y年只能买输入中的第y行电脑,为了不产生混淆,将电脑用编号表示)。显然,某一阶段的最优解并不能一定导致全局的最优解,所以肯定不能用贪心。
    我们从最后的情况来考虑,最后必然是某一个编号为y的电脑,从第y年使用到第n年,而前面的1~y-1年,自己只可能购买编号为1~y-1的电脑使用到y-1年。这样,问题的范围就减小了,从编号为1~n的电脑使用n年,降低到了编号为1~y-1的电脑使用y-1年。经分析,可推出递推式:
    F[n] = min { F[i] + c + m[i+1][n] | 0<=i<=n-1 }
F[n]表示n台电脑使用n年的最低费用

代码:

#include <cstdio>
#include <climits>
#include <cstring>

const int MAX = 1005;
int n, c;
int mend[MAX][MAX];
int f[MAX];
int cost;

bool Input ()
{
    if ( scanf("%d", &c) == EOF )
        return false;
    scanf("%d", &n);
    int i, j;
    for (i=1; i<=n; i++)
    {
        for (j=i; j<=n; j++)
            scanf("%d", &mend[i][j]);
    }
    return true;
}


void Solve ()
{
    int i, j;
    memset(f, 0, sizeof(f));
    for (i=1; i<=n; i++)
    {
        f[i] = INT_MAX;
        for (j=0; j<i; j++)
        {
            if ( f[j] + mend[j+1][i] + c < f[i] )
                f[i] = f[j] + mend[j+1][i] + c;
        }
    }
    printf("%d\n", f[n]);
}

int main ()
{
    while ( Input() )
    {
        Solve ();
    }

    return 0;
}
posted on 2008-01-28 14:45 quxiao 阅读(464) 评论(0)  编辑 收藏 引用 所属分类: ACM

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理