場景中包括多個長度和高度各不相同的平台,地面是最低的平台,高度為零,長度無限,jimmy老鼠在時刻 0 從高於所有平台的某處開始下落,它的下落速度始終為1公尺/秒,當jimmy落到某個平台上時,遊戲者選擇讓它向左還是向右跑,它跑動的速度也是1公尺/秒,當jimmy跑到平台的邊緣時,開始繼續下落,jimmy每次下落的高度不能超過max公尺,不然就會摔死,遊戲也會結束,設計乙個程式,計算jimmy到底地面時的最早時間
第一行是測試資料的組數t(0 <= t <= 20)
每組測試資料的第一行是四個整數 n,x,y,max,用空格分隔
n是平台的數目(不包括地面)
x 和 y 是jimmy開始下落的位置的橫豎座標
max是一次下落的最大高度
接下來的n行每行描述乙個平台,包括三個整數,x1[ i ],x2[ i ] 和 h[ i ]
h[ i ]表示平台的高度
x1[ i ] 和 x2[ i ]表示平台左右端點的橫座標
1 <= n <= 1000,-20000 <= x,x1[i], x2[i] <= 20000,0 < h[i] < y <= 20000(i = 1..n)
補充:所有座標的單位都是公尺,jimmy的大小和平台的厚度均忽略不計,如果jimmy恰好落在某個平台的邊緣,被視為落在平台上,所有的平台均不重疊或相連,測試資料保證問題一定有解
對輸入的每組測試資料,輸出乙個整數,jimmy到達地面時的最早時間
input13
817200
108010
134143
output
23
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define _for(i,a,b) for(int i=a;i#define _unfor(i,a,b) for(int i=a;i>=b;i--)
#define ri(a) scanf("%d",&a)
#define mset(a,val,n) for(int i=0;i#define mset2(a,val,n,m) for(int i=0;i#define fi freopen("d:\\in.txt","r",stdin)
#define fo freopen("d:\\out.txt","w",stdout)
using
namespace std;
typedef
long
long ll;
/*-------下面為主要**-------*/
const
int n=
1005
;const
int m=
20005
;struct time //定義結構體
a[n]
;int dp[n+2]
[2];
// 0:表示第i的木板左邊到底部的最短時間
// 1: 表示第i的木板右邊到底部的最短時間
int n,x,y,max_h;
intcmp
(time c,time b)
//排序函式
void
left
(int i)
//左 k++;}
if(a[i]
.h-a[k]
.h>max_h)
dp[i][0
]=int_max;
else
//這裡的else是最有靈魂的地方:成敗都在這
dp[i][0
]=a[i]
.h;//因為它下面沒木板,直接落地
}void
right
(int i)
//右 k++;}
if(a[i]
.h-a[k]
.h > max_h)
//不能到達下一平台
dp[i][1
]=int_max;
else
dp[i][1
]=a[i]
.h;//因為它下面沒木板,直接落地
}int
main()
int time=
min(dp[0]
[0],dp[0]
[1])
;//取最小值
printf
("%d\n"
,time)
;//輸出結果
}return0;
}
**的簡潔程度取決於對題目的理解程度,下面我說一些對本題的理解
1、場景中包括多個長度和高度各不相同的板子(平台),說明所有板子都是上下參差不齊的,寫**時不用考慮同一平面優先到哪一塊板子,只用考慮不同高度優先下降到哪一塊板子
2、貪心思路:下降到距離差更大的板子,這咋一看沒問題,但這只是當前狀態最優解,而不是整體最優解(如下圖,明顯第一條路是最優解)
3、採用下降一層回頭看一層的策略,由下圖距離
從三層出發,到二層,回頭看第三層,可以算出時間是
二、三層高度差 + 三層左側距離(設為 t1),再到一層,回頭看第二層和第三層,第一種時間是 t1 + 二層右側距離 + 一二層高度差,第二種時間是一層右側距離+一三層高度差,最後取最小就得出到達第一層所用時間的最優解
那麼我們可以模擬一下,若有很多層,每一層的時間就為t + 回頭看的層數左或右側距離 + 回頭看的層數與本層數高度差,而 t 即回頭看的那層到最頂層所用的最優時間,再取最小值,因此這樣就可以得出到達最底層所用時間的最優解
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define _for(i,a,b) for(int i=a;i#define _unfor(i,a,b) for(int i=a;i>=b;i--)
#define ri(a) scanf("%d",&a)
#define mset(a,val,n) for(int i=0;i#define mset2(a,val,n,m) for(int i=0;i#define fi freopen("d:\\in.txt","r",stdin)
#define fo freopen("d:\\out.txt","w",stdout)
using
namespace std;
typedef
long
long ll;
/*-------下面為主要**-------*/
const
int n=
1005
;//最大層數
const
int m=
20005
;//絕對值最大座標
struct time
a[n]
;//n層板子
int dp[n]
;//代表當前當前層到最頂層的最短時間
int n,x,y,max_h;
intcmp
(time c,time b)
//排序函式
void
back
(int i)
if(a[k]
.x2 >= a[i]
.x1 && a[k]
.x2 <= a[i]
.x2)
if(i==0)
dp[i]
=max
(tmp1,tmp2)
; k++
;//再回頭看上一層}}
intmain()
printf
("%d\n"
,dp[0]
);}return0;
}
動態規劃(二) Help Jimmy 滑雪
if 板子k左端正下方沒有別的板子 else if 板子k左端正下方的板子編號是m 實現 poj1661 help himmy 這樣效率太低了,一早上沒看幾個題 要是不是特別好看懂,先把偽 寫出來就比較好懂了 分析 將板子由高到低按從0到n編號,起始點的為0 不妨認為jimmy開始的位置是乙個編號為...
POJ1661Help Jimmy(動態規劃)
description help jimmy 是在下圖所示的場景上完成的遊戲。場景中包括多個長度和高度各不相同的平台。地面是最低的平台,高度為零,長度無限。jimmy老鼠在時刻0從高於所有平台的某處開始下落,它的下落速度始終為1公尺 秒。當jimmy落到某個平台上時,遊戲者選擇讓它向左還是向右跑,它...
poj 1661 Help Jimmy 動態規劃
題意 給n個用左端點 右端點 高度標識的平台,問乙個下落速度,移動速度均為1的點下落到地面的最小時間,其中每次下落距離不能超過輸入值max.分析 動態規劃ldp i 表示從第i塊木板左邊下落到地面的最小時間,rdp i 表示從第i塊木板右邊下落到地面的最小時間。poj 1661 sep9 inclu...