您的位置:首页 > 其它

hdu 4844 公路巡逻 dp(略难)

2016-07-10 10:15 295 查看


公路巡逻

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)

Total Submission(s): 89    Accepted Submission(s): 7


Problem Description

   在一条没有分岔的高速公路上有n个关口,相邻两个关口之间的距离都是10km。所有车辆在这条高速公路上的最低速度为60km/h,最高速度为120km/h,并且只能在关口处改变速度。

   巡逻的方式是在某个时刻Ti从第ni个关口派出一辆巡逻车匀速驶抵第(ni+1)个关口,路上耗费的时间为ti秒。

两辆车相遇是指它们之间发生超车或者两车同时到达某关口(同时出发不算相遇)。

   巡逻部门想知道一辆于6点整从第1个关口出发去第n个关口的车(称为目标车)最少会与多少辆巡逻车相遇,请编程计算之。假设所有车辆到达关口的时刻都是整秒。

 

Input

输入有多组数据。对于每一组数据,第一行为两个用空格隔开的整数,分别为关口数n和巡逻车数m。(1<n<50,1<m<300),接下来的m行每一行为一辆巡逻车的信息(按出发位置递增排序),格式为ni Ti ti,三项用空格隔开,分别表示第i辆巡逻车的出发位置、出发时刻和路上耗费的时间,其中ni和ti为整数,Ti形如hhmmss,表示时、分、秒,采用24小时制,不足两位的数用前置0补齐。(1<=ni<n,05:00:00<=Ti<=23:00:00,300<=ti<=600)

 

Output

   对于每一组数据,输出两行:第一行为目标车与巡逻车相遇次数,第二行为目标车与巡逻车相遇次数最少时最早到达第n个关口的时刻(格式同输入中的Ti)。每一组数据之后保留一个空行。

 

Sample Input

3 2
1 060000 301
2 060300 600

 

Sample Output

0
061301

 

Source

CTSC2000

 

Recommend

We have carefully selected several similar problems for you:  5717 5716 5715 5714 5713 

 

Statistic | Submit | Discuss | Note

题目比较复杂,但是实质很简单。

1.目标车辆不可能在任何一站停靠,必须不停的前进

2.根据公路上的最小速度60km/h和120km/h,而且每一站间的距离为10km,可以求出目标车辆每经过一站花费的时间是[300,600]s

3.巡逻车辆的行驶方向是固定的。

4.在任何一站,目标车辆出发到下一站与巡逻车相遇的次数仅依赖于当前所处的时间还有该站出发的巡逻的时刻表。

5.根据题意,如果说发生相遇,无非就是三种情况:

  假如对于同一站而言,A车和B车都是到下一站的。

  设A车出发时间为stA,到达时间为etA。B车出发时间为stB,到达时间为etB。

1)  stA==stB&&etA==etB   (同时出发,同时到达)

2) stA>stB   &&etA<=etB  (A车出发时间晚于B,但是到达时间却不晚于B,即A车中途超过B或者同时到达终点)

3) 类似于2) ,只不过是调换A、B,即B车超过A

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;

#define all(x) (x).begin(), (x).end()
#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)
#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)
const int INF =0x3f3f3f3f;
const int maxn=50;
const int Tmin=300;
const int Tmax=600;
const int maxt=6*3600+300*50;
int n,m;

int dp[maxn+3][maxt+3];

struct Node
{
int st,et;
Node(){}
Node(int st,int et):st(st),et(et){}
bool operator<(const Node & y)const
{

return st<y.st;

}

};
vector<Node >G[maxn+10];
inline void init()
{
for1(i,n)
{
G[i].clear();
}
}
void input()
{
int x,st,et;
string s;
for1(i,m)
{
cin>>x>>s>>et;
st=10*(s[0]-'0')+s[1]-'0';
st*=3600;
st+=  60* (10*(s[2]-'0')+s[3]-'0' ) ;
st+= 10*(s[4]-'0')+s[5]-'0';
et+=st;//我去,掉了
G[x].push_back(Node(st,et));
}

for1(i,n)
{
sort(all(G[i]));
}

}

int cal(int st,int et,int x)
{
int p=lower_bound(all(G[x]),Node(st,0))-G[x].begin();
int cnt=0;
for(int i=p;i<G[x].size();i++)//G[x][i].st>=st
{
if(G[x][i].st==st&&G[x][i].et==et||G[x][i].st!=st&&G[x][i].et<=et)
{
cnt++;
}

}
p=upper_bound(all(G[x]),Node(st-1,0))-G[x].begin();

for(int i=0;i<p;i++)//G[x][i].st<st
{
if(G[x][i].et >=et )  cnt++;
}
return cnt;

}

void work()
{

memset(dp,0x3f,(n+1)*sizeof dp[0]);
dp[1][6*3600]=0;
for1(i,n-1)
{
int st=6*3600+(i-1)*300;
int ed=6*3600+(i-1)*600;
for(int t=st;t<=ed;t++)
{
for(int add=Tmin;add<=Tmax;add++)
{
int t2=t+add;
int tmp=cal( t,t2,i  );
dp[i+1][t2]=min(dp[i+1][t2],dp[i][t]+tmp);

}

}
}

int ans=INF,best=-1;
int st=6*3600+(n-1)*300;
int ed=6*3600+(n-1)*600;
for(int t=ed;t>=st;t--)
{
if(ans>=dp
[t])
{
ans=dp
[t];
best=t;
}
}
printf("%d\n",ans);
int hh,mm,ss;
ss=best%60;
best/=60;
mm=best%60;
best/=60;
hh=best;

printf("%02d%02d%02d\n",hh,mm,ss);
}
int main()
{
std::ios::sync_with_stdio(false);

int kase=0;
while(cin>>n>>m)
{
if(kase++)  putchar('\n');

init();
input();
work();
}

return 0;
}
/*

第二辆巡逻车
3 2
1 060000 301
2 060300 600

6*3600+3*60=21600+180=21780
出发到          22380

第1站到达时间  21600+300=21900
第二站到达时间范围   22200  22500

样例输出061301   21600+13*60+1=21600+781=22381

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: