NOIP 2005過河(DP 路徑壓縮)

2022-08-01 16:57:15 字數 1555 閱讀 7676

dp[i]表示青蛙跳到位置i經過的最小石子數,從dp[i-j]轉移過里,s<=j<=t。初始狀態:dp[0]=0;

最後統計答案是從[n,n+t)區間中找出最小dp值。(n+t青蛙跳不到,所以開區間)

#include#include

#include

#include

#include

#include

using

namespace

std;

intl,s,t,m;

int a[107

];int b[11007

];int dp[11007

];int

main()

memset(dp,

63,sizeof

(dp));

dp[0]=0;

for(int i=s;i) }

int ans=99999;

for(int i=l;i)

printf(

"%d\n

",ans);

return

0;

}

滿分做法:

觀察資料範圍l<=1e9,這麼大陣列肯定存不下來,所以考慮路徑壓縮。因為s,t是1-10之間的數,所以無論青蛙怎麼跳,他都能從當前位置i

跳到i+2520*x的位置,

因為2520是1-10的最小公倍數,他的因子包含1-10所有數。對相鄰兩個石子的距離進行路徑壓縮,對2520取模(因為中間空餘的長度大於2520,青蛙可以直接跳過,不會對答案有影響),

這樣可以大大縮短橋的長度。重新更新石子的位置,最後橋長就等於最後石子的位置,其他操作和30分一樣.

#include#include

#include

#include

#include

#include

using

namespace

std;

const

int maxm=1e6+7

;int

l,s,t,m;

int a[117

];int

b[maxm];

int d[117

];int

dp[maxm];

intmain()

sort(a+1,a+m+1);//

題目沒說公升序排列

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

路徑壓縮

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

l=a[m];//

更新新長度

memset(dp,63,sizeof

(dp));

dp[0]=0;

for(int i=s;i) }

int ans=99999;

for(int i=l;i)

printf(

"%d\n

",ans);

return

0;

}

NOIP2005 狀壓DP 過河

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

NOIP 2005提高組 過河(狀壓DP) 詳解

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

NOIP2005過河 DP 狀態壓縮

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