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