• Kickstart Round D 2017 problem A sightseeing 一道DP


    这是现场完整做出来的唯一一道题Orz。。而且还调了很久的bug。还是太弱了。

    Problem

    When you travel, you like to spend time sightseeing in as many cities as possible, but sometimes you might not be able to because you need to catch the bus to the next city. To maximize your travel enjoyment, you decide to write a program to optimize your schedule.

    You begin at city 1 at time 0 and plan to travel to cities 2 to N in ascending order, visiting every city. There is a bus service from every city i to the next city i + 1. The i-th bus service runs on a schedule that is specified by 3 integers: SiFi and Di, the start time, frequency and ride duration. Formally, this means that there is a bus leaving from city i at all times Si+ xFi, where x is an integer and x ≥ 0, and the bus takes Di time to reach city i + 1.

    At each city between 1 and N - 1, inclusive, you can decide to spend Ts time sightseeing before waiting for the next bus, or you can immediately wait for the next bus. You cannot go sightseeing multiple times in the same city. You may assume that boarding and leaving buses takes no time. You must arrive at city N by time Tf at the latest. (Note that you cannot go sightseeing in city N, even if you arrive early. There's nothing to see there!)

    What is the maximum number of cities you can go sightseeing in?

    Input

    The input starts with one line containing one integer T, which is the number of test cases. T test cases follow.

    Each test case begins with a line containing 3 integers, NTs and Tf, representing the number of cities, the time taken for sightseeing in any city, and the latest time you can arrive in city N.

    This is followed by N - 1 lines. On the i-th line, there are 3 integers, SiFi and Di, indicating the start time, frequency, and duration of buses travelling from city i to city i + 1.

    Output

    For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the maximum number of cities you can go sightseeing in such that you can still arrive at city N by time Tf at the latest. If it is impossible to arrive at city N by time Tf, output Case #x: IMPOSSIBLE.

    Limits

    1 ≤ T ≤ 100.

    Small dataset

    2 ≤ N ≤ 16.
    1 ≤ Si ≤ 5000.
    1 ≤ Fi ≤ 5000.
    1 ≤ Di ≤ 5000.
    1 ≤ Ts ≤ 5000.
    1 ≤ Tf ≤ 5000.

    Large dataset

    2 ≤ N ≤ 2000.
    1 ≤ Si ≤ 109.
    1 ≤ Fi ≤ 109.
    1 ≤ Di ≤ 109.
    1 ≤ Ts ≤ 109.
    1 ≤ Tf ≤ 109.

    Sample


    Input 
     

    Output 
     
    4
    4 3 12
    3 2 1
    6 2 2
    1 3 2
    3 2 30
    1 2 27
    3 2 1
    4 1 11
    2 1 2
    4 1 5
    8 2 2
    5 10 5000
    14 27 31
    27 11 44
    30 8 20
    2000 4000 3
    
    
    Case #1: 2
    Case #2: 0
    Case #3: IMPOSSIBLE
    Case #4: 4
    
    
    

    In the first test case, you can go sightseeing in city 1, catching the bus leaving at time 3 and arriving at time 4. You can go sightseeing in city 2, leaving on the bus at time 8. When you arrive in city 3 at time 10 you immediately board the next bus and arrive in city 4 just in time at time 12.

    大致思路:以dp[j][k]表示到达第j个城市,路上看过k次风景的最小时间,设计状态转移方程即可。

    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cmath>
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    using namespace std;
    long long int dp[2010][2010];
    int s[2010];
    int f[2010];
    int d[2010];
    long long int seartim(int num,long long int timenow)
    {
        //if(num==1&&timenow==3) printf("num=%d snum=%d dnum=%d f[num]=%d",num,s[num],d[num],f[num]);
        if(timenow<=s[num]) return s[num]+d[num];
        else
        {
            if(f[num]==0) return timenow+d[num];
            int t=(timenow-s[num])/f[num];
            if((timenow-s[num])%f[num]>0) t=t+1;
            return (long long int)s[num]+t*f[num]+d[num];
        }
    }
    int main()
    {
        freopen("A-large.in","r",stdin);
        freopen("A-large.out","w",stdout);
        int T;
        scanf("%d",&T);
        int n,spend,ddl,ans;
        rep(i,1,T)
        {
            scanf("%d%d%d",&n,&spend,&ddl);
            rep(j,1,2009)
            {
                rep(k,1,2009) dp[j][k]=ddl+1;
            }
            rep(j,1,n-1)
            {
                scanf("%d%d%d",&s[j],&f[j],&d[j]);
            }
            dp[1][0]=0;
            rep(j,1,n-1)
            {
                rep(k,0,j-1) dp[j+1][k]=seartim(j,dp[j][k]);
                rep(k,1,j)
                {
                  //  printf("spend=%d
    ",spend);
                 //   if(i==1&&j==1) printf("dp=%d  
    ",seartim(j,dp[j][k-1]+spend));
                    dp[j+1][k]=min(dp[j+1][k],seartim(j,dp[j][k-1]+spend));
                }
            }
            ans=n;
            rep(j,0,n-1)
            {
                if(dp[n][j]<=ddl) ans=j;
            }
            if(ans==n) printf("Case #%d: IMPOSSIBLE
    ",i);
            else printf("Case #%d: %d
    ",i,ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Oracle Relink RAC Binary Options 说明
    Oracle 10g 对象 默认 ITL 数量 测试
    Oracle 相关的专业术语 说明
    Oracle 11g 新特性 自适应游标共享(Adaptive Cursor Sharing: ACS) 说明
    symbian 学习笔记(1) 基础
    symbian 学习笔记(3) 手机独有
    计算机体系结构几个常用的知识点记录
    数据结构和算法笔记(3)
    windows mobile 通用曾抽象
    一些简单常用算法整理学习
  • 原文地址:https://www.cnblogs.com/zhixingr/p/7250975.html
Copyright © 2020-2023  润新知