蘇塞克島是乙個有著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 ...