UVA1025

这是一道DP题。

感觉稍微有一点感悟,dp就像是一棵树的底层树叶,我们要做的就是往上开始堆。

这道题有两个变量,一个是时间,一个是位置。边界就是t = T,s(站台) = n时,d[t][s] = 0;表示的是你需要在站台等待的时间,仅指你不在地铁上的时间。所以有三种状态:一种是你上一秒在站台上等,现在再等一秒钟;第二种是左边有车过来,所以等待的时间就是到下一个站台的等待时间(车上的时间不算)。我们从d[T][n]开始往前堆,就会得到最优解。

#include <iostream>
#include <bits/stdc++.h>
#define maxn 1000
#define INF 0x3f3f3f3f

using namespace std;
int t[maxn];
int hasTrain[maxn][maxn][2];//t s
int d[maxn][maxn];

int main() {
    int n,T;
    int M1,M2;
    int d1,d2;
    int kase = 0;
    while (cin>>n && n){
        cin>>T;
        memset(hasTrain,0, sizeof(hasTrain));
        memset(t,0,sizeof(t));
        memset(d,INF, sizeof(d));
        for(int i = 1;i<=n-1;i++){
            cin>>t[i];
        }
        //M1
        cin>>M1;
        int sum = 0;
        for(int i = 1;i<=M1;i++)
        {
            cin>>d1;
            //deal
            hasTrain[d1][1][0] = 1;
            sum = d1;
            for(int j = 1;j<=n-1;j++){
                sum+=t[j];
                hasTrain[sum][j+1][0] = 1;
            }
        }

        //M2
        cin>>M2;
        for(int i = 1;i<=M2;i++)
        {
            cin>>d2;
            //deal
            hasTrain[d2][n][1] = 1;
            sum = d2;
            for(int j = n-1;j>=1;j--){
                sum+=t[j];
                hasTrain[sum][j][1] = 1;
            }
        }

        //deal
        d[T][n] = 0;
        for(int i = T-1;i>=0;i--){
            for(int j = n;j>=1;j--){
                d[i][j] = d[i+1][j] + 1;
                //--->
                if(j<n && i+t[j]<=T && hasTrain[i][j][0] ){
                    d[i][j] = min(d[i][j],d[i+t[j]][j+1]);
                }
                //<---
                if(j>1 && i + t[j-1]<=T && hasTrain[i][j][1]){
                    d[i][j] = min(d[i][j],d[i+t[j-1]][j-1]);

                }
            }
        }

        cout<<"Case Number "<<++kase<<": ";
        if(d[0][1]>=INF) cout<<"impossible\n";
        else cout<<d[0][1]<<"\n";

    }
    return 0;
}
/**
4
55
5 10 15
4
0 5 10 20
4
0 5 10 15
4
18
1 2 3
5
0 3 6 10 12
6
0 3 5 7 12 15
2
30
20
1
20
7
1 3 5 7 11 13 17
0
**/

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值