張老師的旅行(區間dp)

張老師的旅行
鏈接:https://ac.nowcoder.com/acm/contest/5477/C
來源:牛客網

時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 262144K,其他語言524288K
64bit IO Format: %lld
題目描述
張老師到了一個王國去旅遊,王國有n個景點,張老師到達這個城市所在的車站恰好位於第x個景點,這個王國非常特別,恰好所有著名的景點都在分佈在直線上,每個景點在座標pi上(單位:公里),張老師身體非常好,每走一公里花費一分鐘。每個景點都有一個打卡點,並且必須在不遲於相應的時間(時間從張老師到達王國開始計算)前到達才能打卡成功並且給以一個打卡標記,集齊所這些標記就能獲得一個大禮包。由於張老師非常想要大禮包,並且因爲張老師還着急去下一個王國旅遊,所以張老師希望用的時間儘量少,你能幫幫張老師嗎?

輸入描述:
輸入的第一行,包含一個整數n(1≤n≤1000)。
第二行包含n個整數pi(1≤pi≤100000),第i個整數pi爲第i個景點的座標(座標從小到大排列)。
最後一行包含n個整數ti(0≤ti≤10,000,000),ti表示第i個景點最遲到達的時間,時間爲0則表示張老師所在車站的位置且只有一個爲0。

輸出描述:
輸出所需的最少時間,若無解輸出-1。

輸入
4
1 2 3 4
0 1 2 3
輸出
3

  • 區間DP,dp[ l ][ r ][ num ]代表走完 l 到 r 區間,所用的最少時間,num爲0代表最後的落腳點在 l ,1代表最後的落腳點在 r (走完一段區間,落腳點一定是兩端點),dp[ i ][ i ] = 0,先求小區間,再由小區間求大區間,dp的時候判斷到達時間有效纔可以dp,結果爲 min(dp[1][n][0],dp[1][n][1])
  • 狀態轉移方程
    dp[j][endd][0] = min(dp[j][endd][0],dp[j+1][endd][0]+a[j+1].p-a[j].p);
    dp[j][endd][0] = min(dp[j][endd][0],dp[j+1][endd][1]+a[endd].p-a[j].p);
    dp[j][endd][1] = min(dp[j][endd][1],dp[j][endd-1][0]+a[endd].p-a[j].p);
    dp[j][endd][1] = min(dp[j][endd][1],dp[j][endd-1][1]+a[endd].p-a[endd-1].p);
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e3+9;
struct node
{
    long long p,t;
} a[maxn];
long long dp[maxn][maxn][2];
bool cmp(node a,node b)
{
    return a.p<b.p;
}
int main()
{

    ios::sync_with_stdio(false);
    long long i,j,m,n;
    cin>>n;
    memset(dp,0x3f3f3f3f3f3f3f3f,sizeof(dp));
    for(i = 1; i<=n; i++)
    {
        cin>>a[i].p;
        dp[i][i][0]=dp[i][i][1] = 0;
    }
    for(i = 1; i<=n; i++)
    {
        cin>>a[i].t;
    }
    sort(a+1,a+n+1,cmp);
    for(i = 2; i<=n; i++)
    {
        for(j = 1; j<=n-i+1; j++)
        {
            long long endd = j+i-1;
            if(dp[j+1][endd][0]+a[j+1].p-a[j].p<=a[j].t)
                dp[j][endd][0] = min(dp[j][endd][0],dp[j+1][endd][0]+a[j+1].p-a[j].p);
            if(dp[j+1][endd][1]+a[endd].p-a[j].p<=a[j].t)
                dp[j][endd][0] = min(dp[j][endd][0],dp[j+1][endd][1]+a[endd].p-a[j].p);
            if(dp[j][endd-1][0]+a[endd].p-a[j].p<=a[endd].t)
                dp[j][endd][1] = min(dp[j][endd][1],dp[j][endd-1][0]+a[endd].p-a[j].p);
            if(dp[j][endd-1][1]+a[endd].p-a[endd-1].p<=a[endd].t)
                dp[j][endd][1] = min(dp[j][endd][1],dp[j][endd-1][1]+a[endd].p-a[endd-1].p);
        }
    }
    long long ans = min(dp[1][n][0],dp[1][n][1]);
    if(ans==0x3f3f3f3f3f3f3f3f)
        cout<<"-1"<<endl;
    else
    cout<<ans<<endl;

    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章