描述
在河上有一座獨木橋,乙隻青蛙想沿著獨木橋從河的一側跳到另一側。在橋上有一些石子,青蛙很討厭踩在這些石子上。由於橋的長度和青蛙一次跳過的距離都是正整數,我們可以把獨木橋上青蛙可能到達的點看成數軸上的一串整點:0,1,……,l(其中l是橋的長度)。座標為0的點表示橋的起點,座標為l的點表示橋的終點。青蛙從橋的起點開始,不停的向終點方向跳躍。一次跳躍的距離是s到t之間的任意正整數(包括s,t)。當青蛙跳到或跳過座標為l的點時,就算青蛙已經跳出了獨木橋。
題目給出獨木橋的長度l,青蛙跳躍的距離範圍s,t,橋上石子的位置。你的任務是確定青蛙要想過河,最少需要踩到的石子數。
對於30%的資料,l <= 10000;
對於全部的資料,l <= 10^9。
格式 輸入格式
輸入的第一行有乙個正整數l(1 <= l <= 10^9),表示獨木橋的長度。第二行有三個正整數s,t,m,分別表示青蛙一次跳躍的最小距離,最大距離,及橋上石子的個數,其中1 <= s <= t <= 10,1 <= m <= 100。第三行有m個不同的正整數分別表示這m個石子在數軸上的位置(資料保證橋的起點和終點處沒有石子)。所有相鄰的整數之間用乙個空格隔開。
輸出格式
輸出只包括乙個整數,表示青蛙過河最少需要踩到的石子數。
樣例1
樣例輸入1
10 2 3 5
2 3 5 6 7
樣例輸出1
這道題是狀態壓縮dp的經典例題,至於狀壓dp,就是將沒用的距離縮短,名字很高階,其實並不難,後面我們詳細解釋
本來這道題是一道十分普通的dp題,但大家可能都注意到l <= 10^9,對於如此大的資料,如果暴力dp,時間空間都會爆,所以就需要狀壓把沒用的長度壓縮掉
首先,我們不考慮長度的問題,看一下dp
這道題的dp思路並不難,就是迴圈列舉所有距離,每個距離再迴圈當前這步跳的距離s-t就行了。
a[i]表示位置i上有沒有石頭,有就是1,否則是0
f[i]表示跳到位置i的過程中踩到的最小石頭數
j表示當前這步跳的距離
狀態轉移方程:
f[i]=min(f[i],f[i-j]+a[i]);//十分簡單,f[i-j]+a[i]就是相當於這一步跳j踩到的石頭數
我們看到題目就會發現,l最大為10^9,而m最大只有100,可見石頭與石頭之間的距離是很大的,所以就要想辦法把每兩個石頭之間的距離縮短。
而壓縮石頭間距離的依據是:由於每次跳能跳s-t,所以從某一固定位置到某一位置p後,任意位置都可以被跳到。
我們用乙個圖來理解這句話(下圖中設s=2,t=4,線段為跳躍過程)
可見對於這種情況,p=3,也就是3以後的所有點都能跳到
對應到題目中,也就是說假如從某一石頭(就是剛剛提到的固定位置)開始跳,有可能在到達下一石頭前,就到達了p(也就是在到達下一石頭前,就能夠跳到所有點),這樣子的話,在p到下一石頭之間的所有距離都是沒有用的,可以被壓縮。
而經過考證,因為s,t都小於10,對於這個範圍最大p值為90,所以我們就把所有石頭兩兩間的距離縮短到90以下(不追求完美主義,90不一定是最優的,但肯定是沒錯的)
#include
#include
#include
#include
using
namespace
std;
int l,s,t,m,rock[101],f[1100000],a[1100000];
//a[i]表示位置i上有沒有石頭,有就是1,否則是0
//f[i]表示跳到位置i的過程中踩到的最小石頭數
void specialjudge()
}cout
l=(l-rock[m])%90+rock[m];//把最後的l也往前移動
for (int i=1;i<=m;i++)
}void dp() //dp,實際上思想十分基礎 }}
int ans=0x7f;
for (int i=l;i<=l+t;i++)
sort(rock+1,rock+m+1);
if (s==t)
compress();
dp();
return
0;}
noip2005提高組過河
介於被這道題折磨了一晚上,因此很有必要記錄下來做動態規劃及狀態壓縮中易錯事項。題目大意 共m個石子,求青蛙每次以s到t步從座標0跳過座標l踩到的最小石子數。樣例資料 輸入10 2 3 5 2 3 5 6 7 輸出資料範圍 1 l 10 9 1 s t 10,1 m 100 初看此題,可以想到動態規劃...
NOIP2005提高組 過河
在河上有一座獨木橋,乙隻青蛙想沿著獨木橋從河的一側跳到另一側。在橋上有一些石子,青蛙很討厭踩在這些石子上。由於橋的長度和青蛙一次跳過的距離都是正整數,我們可以把獨木橋上青蛙可能到達的點看成數軸上的一串整點 0,1,l 其中l是橋的長度 座標為0的點表示橋的起點,座標為l的點表示橋的終點。青蛙從橋的起...
NOIP2005 狀壓DP 過河
題目描述 題目背景 noip2005提高組試題2。在河上有一座獨木橋,乙隻青蛙想沿著獨木橋從河的一側跳到另一側。在橋上有一些石子,青蛙很討厭踩在這些石子上。由於橋的長度和青蛙一次跳過的距離都是正整數,我們可以把獨木橋上青蛙可能到達的點看成數軸上的一串整點 0,1,l 其中l是橋的長度 座標為 0 的...