HDU 1039 修路

针对某省因干旱导致B山区缺水的问题,本篇介绍了一种算法,旨在通过合理分配工程队修建从A城到B山区的道路,计算出完成整个工程项目所需的最短时间。文章详细解释了状态转移方程,并提供了具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

前段时间,某省发生干旱,B山区的居民缺乏生活用水,现在需要从A城市修一条通往B山区的路。假设有A城市通往B山区的路由m条连续的路段组成,现在将这m条路段承包给n个工程队(m≤ 300)。为了修路的便利,每个工程队只能分配到连续的若干条路段(当然也可能只分配到一条路段或未分配到路段)。假设每个工程队修路的效率一样,即每修长度为1的路段所需的时间为1。现在给出路段的数量m,工程队的数量n,以及m条路段的长度(这m条路段的长度是按照从A城市往B山区的方向依次给出,每条路段的长度均小于1000),需要你计算出修完整条路所需的最短的时间(即耗时最长的工程队所用的时间)。

Input

第一行是测试样例的个数,接下来是T个测试样例,每个测试样例占2行,第一行是路段的数量m和工程队的数量n,第二行是m条路段的长度。

Output

对于每个测试样例,输出修完整条路所需的最短的时间。

Sample Input

2

4 3

100 200 300 400

9 4

250 100 150 400 550 200 50 700 300

Sample Output

400

900

解题思路

用opt[k][j-1]表示前k条路段由前j-1个工程队修完的最早的时间,用sum[i]表示前i条路段只由1个工程对完成的所需的时间,则sum[i]-sum[k]表示从第K+1条路段到第i条路段由1个工程队完成所需的时间。 

状态转移方程:

 opt[i][j] = max(opt[k][j-1], sum[i]-sum[k]);

 即前i条路段由前j个工程队修完的最早的时间为前k条路段由前j-1个工程队修完的最早的时间和从第K+1条路段到第i条路段由1个工程队完成所需的时间这两者中大的一个。 

 

code:

#include<stdio.h>
#include<stdlib.h>
#define INF 0x3f3f3f3f
int max(int x,int y)
{
    if(x>y)
        return x;
    return y;
}
int main()
{
    int a[302];
    int opt[302][302];
    int sum[302];
    int t,n,m,i,j,tot,k;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&m,&n);
        for(i=1;i<=m;i++)
            scanf("%d",&a[i]);
        sum[0]=0;
        for(i=1;i<=m;i++)
            sum[i]=sum[i-1]+a[i];
        opt[1][1]=sum[1]-sum[0];
        opt[2][1]=sum[2]-sum[0];
        opt[2][2]=max(opt[1][1],sum[2]-sum[1]);
        for(i=3;i<=m;i++)
        {
            opt[i][1]=sum[i]-sum[0];
            for(j=2;j<=i;j++)
            {
                tot=INF;
                for(k=j-1;k<=i-1;k++)
                    if(max(opt[k][j-1],sum[i]-sum[k])<tot)
                        tot=max(opt[k][j-1],sum[i]-sum[k]);
                opt[i][j]=tot;
            }
        }
        printf("%d\n",opt[m][n]);
    }
    return 0;
}

转载于:https://www.cnblogs.com/dream-wind/archive/2012/03/14/2396311.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值