洛谷P1052過河

2022-08-16 15:03:11 字數 1920 閱讀 7425

在河上有一座獨木橋,乙隻青蛙想沿著獨木橋從河的一側跳到另一側。在橋上有一些石子,青蛙很討厭踩在這些石子上。由於橋的長度和青蛙一次跳過的距離都是正整數,我們可以把獨木橋上青蛙可能到達的點看成數軸上的一串整點:0,1,……,l(其中l是橋的長度)。座標為0的點表示橋的起點,座標為l的點表示橋的終點。青蛙從橋的起點開始,不停的向終點方向跳躍。一次跳躍的距離是s到t之間的任意正整數(包括s,t)。當青蛙跳到或跳過座標為l的點時,就算青蛙已經跳出了獨木橋。

題目給出獨木橋的長度l,青蛙跳躍的距離範圍s,t,橋上石子的位置。你的任務是確定青蛙要想過河,最少需要踩到的石子數。

輸入格式:

輸入檔案river.in的第一行有乙個正整數l(1 <= l <=

10^9),表示獨木橋的長度。第二行有三個正整數s,t,m,分別表示青蛙一次跳躍的最小距離,最大距離,及橋上石子的個數,其中1 <= s

<= t <= 10,1 <= m <=

100。第三行有m個不同的正整數分別表示這m個石子在數軸上的位置(資料保證橋的起點和終點處沒有石子)。所有相鄰的整數之間用乙個空格隔開。

輸出格式:

輸出檔案river.out只包括乙個整數,表示青蛙過河最少需要踩到的石子數。

輸入樣例:

10

2 3 5

2 3 5 6 7

輸出樣例:

2
對於30%的資料,l≤10000

對於全部的資料,l≤109

2005提高組第二題

solution:

這題明顯是乙個dp,而且暴力複雜度是o(l*(t-s+1))。

但我們看到這個l非常的大。時間和空間都會超出範圍。

我們觀察到m的值很小,s,t的值都不超過10。因此我們考慮路徑壓縮。

我們可以發現在兩個石頭距離等於lcm(s,s+1,…,t-1,t)的時候,一定有有一種選法可達。因此我們把兩點間的距離對lcm(1,2,3,…,9,10)取模,即對2520取模,即可進行路徑壓縮。

因此記f[i]為跳到第i個時,最小碰到的石頭個數。

因此f[i]=min(f[i],f[i-j]+rock[i])。其中,j從s列舉到t,rock[i]表示第i位是否有石頭。有為1,否則為0。

**:

1 #include2 #include3 #include4 #include5 #include6 #include7

#define lcm 2520

8#define inf 0x3f3f3f3f

9using

namespace

std;

10bool cmp(int a,int

b)13

int min(int a,int

b)16

int num[110],di[110

];17

int ro[300010],dp[300010

];18

intl,s,t,m,ans;

19int

main()

26 sort(num+1,num+1+m,cmp);

27 num[0]=0;28

for(i=1;i<=m;++i)

31for(i=1;i<=m;++i)

34 l=num[m];

35 memset(dp,0x3f,sizeof(dp));dp[0]=0;36

for(i=1;i<=l+t;++i)41}

42}43 ans=inf;

44for(i=l;ii)

47 printf("

%d\n

",ans);

48return0;

49 }

view code

洛谷 P1052 過河

題目 過河 思路 因為l的值太大,而實際有石子的地方卻並不多,所以要先進行離散化。即將每個石子之間的差距都控制在剛好比t大一點的位置,這樣就不會影響最終結果。令f i 表示跳過前i個位置需要最少踩得石頭數量,轉移方程f i min f i j cnt i f i j s,t 注意最後的輸出是min,...

洛谷 P1052過河

這個是題幹 這是一道noip2005年的提高組的題,那道題一看,就是要用動態規劃,狀態轉移方程也十分簡單。只需要考慮是從哪個地方來的,看看即將到達的點是否有石子。用一維陣列 f x 表示第x位的步數 額,這只是30分的寫法,l 的取值太大,陣列承受不了 之後,我又想騙一點分,就特判了一下s t的情況...

洛谷 P1052 過河

在河上有一座獨木橋,乙隻青蛙想沿著獨木橋從河的一側跳到另一側。在橋上有一些石子,青蛙很討厭踩在這些石子上。由於橋的長度和青蛙一次跳過的距離都是正整數,我們可以把獨木橋上青蛙可能到達的點看成數軸上的一串整點 0,1,l 其中l是橋的長度 座標為0的點表示橋的起點,座標為l的點表示橋的終點。青蛙從橋的起...