codeforces985E 2000ポイントDP

トピックポータル

質問の意味:

Nボールは、各ボールは、AIの数、2つの整数k及びdが存在します。今では、n個のボールを複数に分割スタックする、スタックの数に制限がない、少なくともk個のボールで含む各スタックは、各スタックの数が最大値 - 最小値Dを超えません。あなたは、このような株式杭かどうかを尋ねることができます。

データ範囲:1 <= K <= N <= 5E5、0 <= D <= 1E9、1 <= aiを<= 1E9。

ソリューション:

より良い結果を作る可能性が高いパイルポイントの現在の数を考えると、それはDPに注意する必要があります。

DP [I] = 1つの意味iは点の数は、スタックの要件を満たすようにすることができるフロント、DP [I] = 0は、iはサブスタックの要件を満たす前に実施されていない番号を示します。

0は初期状態であり、有効な数、すなわちDP [0] = 1です。

この数は、N並べ替え、小から大へ横断します。

二つの法的制限が区間[L、R]描くことができる、Lを満たすAL> =愛 - D最小添字、R <= I - K。

DPなら[J] = 1及びj∈[L、R]、DP [I] = 1。

GET DP [J] [L. R]区間最大値配列DPを求める過程でのプロセスです。

私は状態ツリーラインの内側を保つので、私は、オープンDP配列ませんでした。

経験:

設定時の初期状態は、図2(a)において得られたパラメータを変更することを忘れ。

十分に安定しません。

これはDPが、時間を意識選手の異なるレベルをやっているだろう実現するとき、私は、1ないししばらく考える必要があった問題です。

確かに、以前に遭遇したこの問題のいくつかのレベルを上げるあなたはそれについて考える問題への解決策を参照してください、そして今(ただし見誤ったテストケース)とは独立して行うことができます。

コード:

#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
const int maxn = 5e5 + 5 ;
int n , k , d ;
int a[maxn] ;
bool max1[maxn << 2] ;
int ls(int x)
{
    return x << 1 ;
}
int rs(int x)
{
    return x << 1 | 1 ;
}
void update(int id , int l , int r , int x , bool y)
{
	int mid = (l + r) / 2 ;
	if(l == r && l == x)
	{
		max1[id] = y ;
		return ;
	}
	if(x <= mid)
	  update(ls(id) , l , mid , x , y) ;
	else
	  update(rs(id) , mid + 1 , r , x , y) ;
	max1[id] = max(max1[ls(id)] , max1[rs(id)]) ;
}
bool query(int id , int l , int r , int x , int y)
{
    if(x > y)  return 0 ;
	bool ans = 0 ;
	int mid = (l + r) / 2 ;
	if(x <= l && r <= y)
	  return max1[id] ;
	if(x <= mid) ans = max(ans , query(ls(id) , l , mid , x , y)) ;
	if(y > mid)  ans = max(ans , query(rs(id) , mid + 1 , r , x , y)) ;
	return ans ;
}
void solve(int i)
{
	int l = lower_bound(a + 1 , a + i + 1 , a[i] - d) - a ;
	int r = i - k ;
	l -- ;
	l = max(l , 0) ;
	bool x = query(1 , 0 , n , l , r) ;
	if(x)  update(1 , 0 , n , i , 1) ;
}
int main()
{
	scanf("%d%d%d" , &n , &k , &d) ;
	for(int i = 1 ; i <= n ; i ++)  scanf("%d" , &a[i]) ;
	sort(a + 1 , a + n + 1) ;
	update(1 , 0 , n , 0 , 1) ;
	for(int i = 1 ; i <= n ; i ++)  
	  solve(i) ;
	if(query(1 , 0 , n , n , n))  printf("YES\n") ;
	else  printf("NO\n") ;
	return 0 ;
}

 

彼は187元の記事を発表 ウォン称賛12 ビュー10000 +

おすすめ

転載: blog.csdn.net/Irving0323/article/details/104080459