1. 程式人生 > >【BZOJ4069】[Apio2015]巴厘島的雕塑 按位貪心+DP

【BZOJ4069】[Apio2015]巴厘島的雕塑 按位貪心+DP

put lld bzoj 最大值 != script mes exp xpl

【BZOJ4069】[Apio2015]巴厘島的雕塑

Description

印尼巴厘島的公路上有許多的雕塑,我們來關註它的一條主幹道。 在這條主幹道上一共有 N 座雕塑,為方便起見,我們把這些雕塑從 1 到 N 連續地進行標號,其中第 i 座雕塑的年齡是 Yi 年。為了使這條路的環境更加優美,政府想把這些雕塑分成若幹組,並通過在組與組之間種上一些樹,來吸引更多的遊客來巴厘島。 下面是將雕塑分組的規則: 這些雕塑必須被分為恰好 X 組,其中 A< = X< = B,每組必須含有至少一個雕塑,每個雕塑也必須屬於且只屬於一個組。同一組中的所有雕塑必須位於這條路的連續一段上。 當雕塑被分好組後,對於每個組,我們首先計算出該組所有雕塑的年齡和。 計算所有年齡和按位取或的結果。我們這個值把稱為這一分組的最終優美度。 請問政府能得到的最小的最終優美度是多少? 備註:將兩個非負數 P 和 Q 按位取或是這樣進行計算的: 首先把 P 和 Q 轉換成二進制。 設 nP 是 P 的二進制位數,nQ 是 Q 的二進制位數,M 為 nP 和 nQ 中的最大值。P 的二進制表示為 pM−1pM−2…p1p0,Q 的二進制表示為 qM−1qM−2…q1q0,其中 pi 和 qi 分別是 P 和 Q 二進制表示下的第 i 位,第 M−1 位是數的最高位,第 0 位是數的最低位。 P 與 Q 按位取或後的結果是: (pM−1 OR qM−1)(pM−2 OR qM−2)…(p1 OR q1)(p0 OR q0)。其中: 0 OR 0=0 0 OR 1=1 1 OR 0=1 1 OR 1=1

Input

輸入的第一行包含三個用空格分開的整數 N,A,B。

第二行包含 N 個用空格分開的整數 Y1,Y2,…,YN。

Output

輸出一行一個數,表示最小的最終優美度。

Sample Input

6 1 3
8 1 2 1 5 4

Sample Output

11
explanation
將這些雕塑分為 2 組,(8,1,2) 和 (1,5,4),它們的和是 (11) 和 (10),最終優美度是 (11 OR 10)=11。(不難驗證,這也是最終優美度的最小值。)

HINT

子任務 1 (9 分)

1< = N< = 20 1< = A< = B< = N 0< = Yi< = 1000000000 子任務 2 (16 分) 1< = N< = 50 1< = A< = B< = min{20,N} 0< = Yi< = 10 子任務 3 (21 分) 1< = N< = 100 A=1 1< = B< = N 0< = Yi< = 20 子任務 4 (25 分) 1< = N< = 100 1< = A< = B< = N 0< = Yi< = 1000000000 子任務 5 (29 分) 1< = N< = 2000 A=1 1< = B< = N 0< = Yi< = 1000000000

題解

:考慮按位貪心來做。從高到低枚舉答案的每一位,對於當前位,我們先check一下當前位=0能否滿足要求,如果可以,則當前位=0,否則=1。那麽如何check呢?考慮DP,用f[i][j]表示前i個雕塑分成j組是否可行,如果要求當前位=0可以滿足要求,那麽就把所有可能使得當前位!=0的轉移都打上刪除標記即可。

但是這樣的轉移時O(n^3)的啊,於是看了題解。。。md你告訴我最後一個子任務A=1!!!那麽直接將DP方程該為f[i]表示將前i個雕塑最少能分成幾組,然後轉移就是O(n^2)的了。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
int n,A,B;
bool f[2][110],mp[2010][2010];
int g[2010];
ll ans,s[2010];
bool check(ll v)
{
	if(v<=8)
	{
		v++,v--;
	}
	int i,j,k,d;
	if(A==1)
	{
		memset(g,0x3f,sizeof(g)),g[0]=0;
		for(i=1;i<=n;i++)	for(j=0;j<i;j++)
			if(!mp[i][j]&&!((s[i]-s[j])&v))	g[i]=min(g[i],g[j]+1);	
		return g[n]<=B;
	}
	memset(f[0],0,sizeof(f[0]));
	f[0][0]=1;
	for(i=1;i<=B;i++)
	{
		d=i&1;
		memset(f[d],0,sizeof(f[d]));
		for(j=1;j<=n;j++)	for(k=0;k<j;k++)	if(!mp[j][k]&&!((s[j]-s[k])&v))	f[d][j]|=f[d^1][k];
		if(i>=A&&f[d][n])	return 1;
	}
	return 0;
}

inline int rd()
{
	int ret=0,f=1;	char gc=getchar();
	while(gc<‘0‘||gc>‘9‘)	{if(gc==‘-‘)f=-f;	gc=getchar();}
	while(gc>=‘0‘&&gc<=‘9‘)	ret=ret*10+gc-‘0‘,gc=getchar();
	return ret*f;
}
int main()
{
	scanf("%d%d%d",&n,&A,&B);
	int i,j;
	for(i=1;i<=n;i++)	s[i]=rd()+s[i-1];
	for(ll k=1ll<<40;k;k>>=1)
	{
		if(check(k))
		{
			for(i=1;i<=n;i++)	for(j=0;j<i;j++)	if((s[i]-s[j])&k)	mp[i][j]=1;
		}
		else	ans|=k;
	}
	printf("%lld",ans);
	return 0;
}

【BZOJ4069】[Apio2015]巴厘島的雕塑 按位貪心+DP