HRBUST 1186 青蛙過河 (思路錯了)

在河上有一座獨木橋,一隻青蛙想沿着獨木橋從河的一側跳到另外一側。在橋上有一些石子,青蛙很討厭踩在這些石子上。因爲橋的長度和青蛙一次跳過的距離都是正整數,咱們能夠把獨木橋上青蛙可能到達的點當作數軸上的一串整點:0,1,……,L(其中L是橋的長度)。座標爲0的點表示橋的起點,座標爲L的點表示橋的終點。青蛙從橋的起點開始,不停的向終點方向跳躍。一次跳躍的距離是s到t之間的任意正整數(包括s,t)。當青蛙跳到或跳過座標爲L的點時,就算青蛙已經跳出了獨木橋。
題目給出獨木橋的長度L,青蛙跳躍的距離範圍s,t,橋上石子的位置。你的任務是肯定青蛙要想過河,最少須要踩到的石子數。ios

 

Inputide

有多組測試數據。
對於每組測試數據,第一行四個正整數L, s, t, n(1 <= L <= 10^5, 1 <= s <= t <= 10,1 <= n <= 100),分別表示獨木橋的長度,青蛙一次跳躍的最小距離,最大距離,及橋上石子的個數。第二行有n個不一樣的正整數分別表示這n個石子在數軸上的位置(數據保證橋的起點和終點處沒有石子)。全部相鄰的整數之間用一個空格隔開。測試

 

Outputspa

每組測試數據僅輸出一行,包括一個整數,表示青蛙過河最少須要踩到的石子數。code

 

題解:blog

顯然是一個動態規劃的題目,可是和我想的不太同樣,ci

本來思路是 :以到達石子 i 所在位置所須要踩到的石子數,創建一個2維的表格,開始遞推打表就行,發現寫不出來根本無法斷定。博客

錯因:子問題找錯了,及動態規劃最重要的 divide and conquer (DAC)出錯;string

參照了博客後發現本身的思路不太對,應該直接枚舉青蛙可能到達的全部位置,狀態轉移方程式:dp[i]=min(dp[i], dp[i+j]),dp[i]是指從終點(不肯定)到達i點的cost,找到這個思路後發現這個和數塔那個題目很類似,io

數塔是從多個終點推到起點(不過有2個變量x,y座標),這個也是從多個終點推到一個起點(只有一個變量x,可是題目給了一個範圍致使x還要隨跳躍的距離而變化,這樣又變成了很類似數塔題目,那又是一道模板題,居然以前不會寫 Orz.....)

 

反思:

這種不是很複雜的dp問題,注意好本身的思路,以什麼爲狀態進行轉移,而後開始遞推(相似打表);

 1 #include <iostream>
 2 #include <cstring>
 3 #define min(x,y) ((x)>(y)?(y):(x))
 4 using namespace std;  5 
 6 const int maxn=1e5+20;  7 const int INF=0x3f3f3f3f;  8 
 9 int main () 10 { 11     int dp[maxn]={0},vis[maxn]={0}; 12     int l,s,t,n; 13    while(cin>>l>>s>>t>>n) 14  { 15         memset(dp, 0, sizeof(dp)); 16         memset(vis, 0, sizeof(vis)); 17         for(int i=0; i<n; i++) 18  { 19             int date; cin>>date; 20             vis[date]=1; 21  } 22         
23         for(int i=l-1; i>=0; i--) 24  { 25             dp[i]=INF; 26             for(int j=s; j<=t; j++) 27                 dp[i]=min(dp[i],dp[i+j]); 28             dp[i]+=vis[i]; 29  } 30         cout<<dp[0]<<endl; 31  } 32     return 0; 33 }
相關文章
相關標籤/搜索