1. 程式人生 > >【BZOJ4922】[Lydsy六月月賽]Karp-de-Chant Number 貪心+動態規劃

【BZOJ4922】[Lydsy六月月賽]Karp-de-Chant Number 貪心+動態規劃

ostream 競賽 namespace hint 秘密 動態規劃 += n+1 ems

【BZOJ4922】[Lydsy六月月賽]Karp-de-Chant Number

Description

卡常數被稱為計算機算法競賽之中最神奇的一類數字,主要特點集中於令人捉摸不透,有時候會讓水平很高的選手迷之超時。 普遍認為卡常數是埃及人Qa‘a及後人發現的常數。也可認為是卡普雷卡爾(Kaprekar)常數的別稱。主要用於求解括號序列問題。 據考證,卡(Qa‘a)是古埃及第一王朝的最後一位法老。他發現並研究了一種常數,後世以他的名字叫做卡常數。卡特蘭數的起源也是因為卡的後人與特蘭克斯結婚,生下來的孩子就叫卡特蘭,而他只是發表了祖傳的家書而已。Sereja也是卡的後人,提出括號序列問題,也是從家書裏得到的資料。然而Sereja為了不讓這個秘密公開,於是隱瞞了這道題的真正做法。可是由於卡的後人不是各個都像卡特蘭一樣愛慕虛榮,這一算法也無法找到。“欲見賢人而不以其道,猶欲其入而閉之門也”。卡之常數的奧秘,需要以一顆誠心去追尋。 現給定n個括號序列,你需要選擇若幹序列,將它們按一定的順序從左往右拼接起來,得到一個合法的括號序列。 顯然,這個問題可以用卡常數解決,為了檢驗你是否會卡常數,請寫一個程序,計算可以得到的合法的括號序列的長度的最大值。

Input

第一行包含一個正整數n(1<=n<=300),表示括號序列的個數。 接下來n行,每行一個長度在[1,300]之間的括號序列,僅由小括號構成。

Output

輸出一行一個整數,即最大長度,註意你可以一個序列也不選,此時長度為0。

Sample Input

3
())
((()
)()

Sample Output

10

HINT

按{2,1,3}的順序拼接得到((()()))(),總長度為10。

題解:先用棧求出每個串左邊有多少多余的右括號l,右邊有多少多余的左括號r。那麽我們最終的序列一定是先來一些l<r的,再來一些r<l的。用f[i]表示右面還剩i個多余的左括號時,總長度的最大值,轉移時顯然是背包,但是轉移順序呢?這就是一個經典的貪心模型了。

對於l<r的,顯然我們要先選擇l更小的,因為這樣可以獲得更多的左括號來填掉多余的右括號;對於l>r的就反過來想,先選r更大的。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n,m;
int f[90010];
struct node
{
	int l,r,v;
}p[310];
char str[310];
bool cmp(const node &a,const node &b)
{
	if((a.r>a.l)!=(b.r>b.l))	return (a.r>a.l)>(b.r>b.l);
	if(a.r>a.l)	return a.l<b.l;
	else	return a.r>b.r;
}
int main()
{
	scanf("%d",&n);
	int i,j;
	for(i=1;i<=n;i++)
	{
		scanf("%s",str),p[i].v=strlen(str),m+=p[i].v;
		int top=0;
		for(j=0;j<p[i].v;j++)
		{
			if(str[j]==‘)‘)
			{
				if(top)	top--;
				else	p[i].l++;
			}
			else	top++;
		}
		for(top=0,j=p[i].v-1;j>=0;j--)
		{
			if(str[j]==‘(‘)
			{
				if(top)	top--;
				else	p[i].r++;
			}
			else	top++;
		}
	}
	sort(p+1,p+n+1,cmp);
	memset(f,0xc0,sizeof(f));
	f[0]=0;
	for(i=1;i<=n;i++)
	{
		if(p[i].r>p[i].l)
		{
			for(j=m;j>=p[i].r;j--)	f[j]=max(f[j],f[j+p[i].l-p[i].r]+p[i].v);
		}
		else	for(j=p[i].r;j-p[i].r+p[i].l<=m;j++)	f[j]=max(f[j],f[j-p[i].r+p[i].l]+p[i].v);
	}
	printf("%d",f[0]);
	return 0;
}

【BZOJ4922】[Lydsy六月月賽]Karp-de-Chant Number 貪心+動態規劃