牛客練習賽47

C-DongDong跳一跳

https://ac.nowcoder.com/acm/contest/904/C
題意:給n個數,每個數有 杆的高度 和 權值 兩種屬性,要求從第一個杆上跳,只能從左往右,並且高度差小於等於M,求能獲得的最大的權值

有想過dp,dp[x]表示高度爲x的時候所獲得的最大的權值,就跟揹包問題差不多,但是直接這樣dp是沒有順序的,而且遍歷一次高度,在遍歷一次物品,複雜度也過不去啊

題解:所以就是處理第i個物品的時候,使用前i-1更新的dp來維護出當前的這個高度的最大值,然後這個最大值又用來更新出前i個物品弄出的dp

#include"bits/stdc++.h"
using namespace std;
typedef long long LL;
const int maxn=1e6+5;
LL a[maxn],h[maxn];
LL dp[maxn];//dp[x]表示高度爲x時能獲得的最大值 
int main()
{
	int N,M;
	while(cin>>N>>M)
	{
		LL maxH=0,res=0;
		for(int i=1;i<=N;i++)
		{
			scanf("%lld%lld",h+i,a+i);
			maxH=max(maxH,h[i]);
		}
		for(int i=1;i<=N;i++)
		{
			LL tp=a[i];
			for(int x=max(1LL,h[i]-M);x<=min(maxH,h[i]+M);x++)//高度的絕對值小於等於M 
			{
				tp=max(tp,dp[x]+a[i]);//用前i-1個物品更新出的dp來維護出當前高度的最大值 
			}
			dp[h[i]]=max(dp[h[i]],tp);//dp更新到第i個 
			res=max(res,tp);
		}
		cout<<res<<endl;
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章