小训练1解题报告

小训练1 - D-by qqws99999

D:乡村医院

赶时间请从第四段开始。

此题我用的是二分,题目输出是最小的最远距离,因此二分距离,想到这点我觉得就没问题了。

初看题目,是想将m个医院分配,感觉是DP,DP需要最优子结构和子结构重叠,显然难找不科学。然后搞了半天,看到题目的输出“对每组输入数据输出一个整数,表示最小的最远距离”,就转换了个思路,从距离入手。

显然,一开始二分h=a[n-1]-a[0],l=0,则最远距离mid=(h+l)/2,然后判断以此最远距离是否可建立小于或等于m个医院,覆盖所有村庄。

i=j=k=f=0;

while(i<n&&j<n)

{

if(k==m){f=1;break;}

while(a[i]-a[j]<=mid&&i<n)i++;

j=i-1;

while(a[i]-a[j]<=mid&&i<n)i++;

j=i;

k++;

}

 

f用来标记以mid为最远距离建医院是否可行,k来标记医院个数,然后顺序找距离第j个村庄最远的,满足<=mid的最远村庄i,则在i-1这个村庄位置建立一个医院(因为循环出来的时候a[i]-a[j]>mid了,所以是i-1的位置建),然后将j=i-1,向j位置(这位置上有医院)的右边顺序查找,直到找到某个最远的村庄,其距离到这个有医院的村庄最远,记录下位置j=i(此处不用i-1),然后结束一次查找,增加医院数目k++。如上建立医院,若能在k未到达医院最大上限m的情况下,完成覆盖所有村庄,说明以mid为最远距离建立医院可行,则二分查找小于mid距离的情况,h=mid-1,否则l=mid+1,如此二分查找下去,直到完毕,返回l的值,既为最小的最远距离。

以下以样例1讲解下,

5 2

0 1 2 5 6

二分开始 l=0,h=a[n-1]-a[0]=6,mid=3

判断以mid为最远距离,是否可以建立<=m个医院,使所有村庄都被覆盖。

进入while(i<n&&j<n)

执行while(a[i]-a[j]<=mid&&i<n)i++;

到i=3时跳出循环,j=i-1=2; 则第一个医院在j处。

再执行while(a[i]-a[j]<=mid&&i<n)i++;

在从i=2向右找在mid最远距离内的村庄,一直找到a[4],a[4]-a[2]>mid(6-2>3),退出循环。

j=i;k++;  (j=i=4,k=1)

因为未覆盖完所有村庄,i<n&&j<n,所以继续。

执行while(a[i]-a[j]<=mid&&i<n)i++;

出来i==n;

退出外while循环。

此时根据f标记知道,在最远距离为mid的情况可以覆盖全部村庄,所以h=mid-1,去找比这个最远距离更小的情况,看是否有更小的最远距离。

再次二分……以下类似。

最后得到最小的最远距离。

 


为解题报告打分
暂时不评分

★★
★★★
★★★★
★★★★★
发表您的评论(若贴AC代码或发表禁止言论等违禁行为将被删除并扣除积分)

|返回 |   | 转到页头|
Copyright @ 2008-2024(浙ICP备2022001332号), TZOJ. All Rights Reserved.