uvalive4613

题目大意:
给出n辆车的行走方向,到达时间和通过某段路的时间。
有一个单行道,只能让一辆车经过,为了保证安全两辆车之间经过同一个点的时间差要>=10 问所有的车经过这段路的最少时间。

思路:
dp[i][j][k]代表的是方向向左的经过i辆方向向右的经过j辆最后一辆车的方向为k的时候的经过这段路所需要使用的最少时间。
那么假设前一辆车发车的时间为s,到达终点的时间为t那么当前的车的发车是时间就是max(now.arrive,s + 10),即现在的车所到达这段路的时间和上一辆车发车时间+10的最大值。
那么当前的车到达终点的时间是max(t + 10,max(now.arrive,s + 10) + now.len),即上一辆车到达终点的时间+10与当前车的发车时间加上经过这段路所需要的时间的最大值。

代码:

#include <iostream>
using namespace std;
#include <cstring>
#include <stdio.h>

const int INF = 0x3f3f3f3f;
const int maxn = 250;
char str[5];
struct node {
    int arrive,len;
}l[maxn],r[maxn];

int dp[maxn][maxn][2];

int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        int n;
        scanf("%d",&n);
        int numl = 0,numr = 0;
        int a,b;
        for(int i = 1; i <= n; i++) {
            scanf("%s%d%d",str,&a,&b);
            if(str[0] == 'A') {
                numl++;
                l[numl].arrive = a;
                l[numl].len = b;
            }
            else {
                numr++;
                r[numr].arrive = a;
                r[numr].len = b;
            }
        }
        memset(dp,INF,sizeof(dp));
        dp[0][0][0] = dp[0][0][1] = 0;

        for(int i = 0; i <= numl; i++) {
            for(int j = 0; j <= numr; j++) {
                int st = dp[i][j][1],ed = 0;
                for(int k = i + 1; k <= numl; k++) {
                    st = max(st,l[k].arrive);
                    ed = max(ed,st + l[k].len);
                    dp[k][j][0] = min(dp[k][j][0],ed);
                    st += 10;//下一辆车必须在当前车出发时间加10之后才能出发
                    ed += 10;//下一辆车必须在当前车到达终点时间加10之后才能到达
                }
                st = dp[i][j][0],ed = 0;
                for(int k = j + 1; k <= numr; k++) {
                    st = max(st,r[k].arrive);
                    ed = max(ed,st + r[k].len);
                    dp[i][k][1] = min(dp[i][k][1],ed);
                    st += 10;
                    ed += 10;
                }
            }
        }
        int ans = min(dp[numl][numr][0],dp[numl][numr][1]);
        printf("%d\n",ans);
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值