51nod1455 寶石獵人 DP

2021-08-09 14:30:59 字數 1762 閱讀 9638

蘇塞克島是乙個有著30001個小島的群島,這些小島沿著一條直線均勻間隔分布,從西到東編號為0到30000。眾所周知,這些島上有很多寶石,在蘇塞克島上總共有n顆寶石,並且第i顆寶石位於島 pi上。

小法正好到達0號小島上,他擁有卓越的跳躍能力,能根據以下規則在小島之間向東重複跳躍:

· 首先,他會從0號島跳到d號島

· 此後,他會根據以下規則繼續跳躍,l是上一次跳躍的長度,即,如果他上一次跳躍是從島prev島cur,l= cur-prev。他可以向東做一次長度為l-1,l或l+1的跳躍。即,他將會跳到島 (cur + l - 1), (cur + l) 或 (cur + l + 1)(如果這些島存在)。一次跳躍的長度必須是正數,即,當l=1時,他不能做一次長度為0的跳躍,如果沒有有效的目的地,他將會停止跳躍。

小法將會在跳躍的過程中收集到過的島上的寶石。我們要找到小法能收集的寶石的最大數。

樣例解釋:在第乙個樣例中,最優路徑是0 → 10 (+1寶石) → 19 → 27 (+2寶石) →…

input

輸入的第一行是兩個以空格隔開的整數n和d (1 ≤ n, d ≤ 30000),分別表示蘇塞克島上的寶石數量和小法第一次跳躍的長度。

接下來n行表示這些寶石的位置,第i行(1 ≤ i ≤ n)包含乙個整pi(d ≤ p1 ≤ p2 ≤

… ≤ pn ≤ 30000),表示包含第i顆寶石的小島的編號。

output

輸出小法能收集的寶石的最大數

input示例

4 10

10 21

27 27

output示例

3

#include

#include

#include

#include

#include

using

namespace

std;

const

int maxn=30000+10;

int n,d,a[maxn],dp[maxn][600],ans;

int main()

for(int i=0;i<=d;i++)

memset(dp[i],-1,sizeof(dp[i]));//初始化陣列

dp[d][300]=a[d];//第乙個狀態

for(int i=d+1;i<=30000;i++)//從d+1開始列舉

for(int j=0;j<=599;j++)//保證在地圖內並且上一步跳躍合法

if(dp[i-l][j]==-1)

if(dp[i-l][j-1]==-1)

if(dp[i-l][j+1]==-1)

dp[i][j]=-1;//如果上乙個狀態每乙個都不合法的話就可以判斷此狀態不合法

if(dp[i][j]==-1)continue;

if(dp[i-l][j]!=-1)

dp[i][j]=max(dp[i][j],dp[i-l][j]+a[i]);

if(dp[i-l][j-1]!=-1)

dp[i][j]=max(dp[i][j],dp[i-l][j-1]+a[i]);

if(dp[i-l][j+1]!=-1)

dp[i][j]=max(dp[i][j],dp[i-l][j+1]+a[i]);//三個狀態的dp

ans=max(ans,dp[i][j]);

}printf("%d\n",max(ans,dp[d][300]));//因為第乙個狀態特殊處理,所以要取max

return

0;}

寶石獵人 51Nod 1455 記憶化搜尋

蘇塞克島是乙個有著30001個小島的群島,這些小島沿著一條直線均勻間隔分布,從西到東編號為0到30000。眾所周知,這些島上有很多寶石,在蘇塞克島上總共有n顆寶石,並且第i顆寶石位於島 pi上。小法正好到達0號小島上,他擁有卓越的跳躍能力,能根據以下規則在小島之間向東重複跳躍 首先,他會從0號島跳到...

51Nod 建設國家(DP)

1475 建設國家 基準時間限制 1 秒 空間限制 131072 kb 分值 20難度 3級演算法題 小c現在想建設乙個國家。這個國家中有乙個首都,然後有若干個中間站,還有若干個城市。現在小c想把國家建造成這樣的形狀 選若干 可以是0個 的中間站把他們連成一條直線,然後把首都 首都也是乙個中間站 連...

dp專題 狀態壓縮dp 51nod 1033

在m n 的乙個長方形方格中,用乙個 1 2的骨牌排滿方格。問有多少種不同的排列方法。n 5 例如 3 2 的方格,共有 3種不同的排法。由於方案的數量巨大,只輸出 mod 10 9 7 的結果 input 2個數m n 中間用空格分隔 2 m 10 9 2 n 5 output 輸出數量 mod ...