4922: Karp-de-Chant Number__DP

來源:互聯網
上載者:User

4922: Karp-de-Chant Number
卡常數被稱為電腦演算法競賽之中最神奇的一類數字,主要特點集中於令人捉摸不透,有時候會讓水平很高的選手迷之逾時。
普遍認為卡常數是埃及人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。

新加兩組資料by alone_wolf 2017.6.20

wohenshuai大佬帶飛我
思路就是排序後DP
然後資料範圍300,所以隨便搞
n3 n^3也可以過
那麼問題就是怎麼排序
首先,有用的只有兩個值x,y,分別代表,這個字串的最小值和總和
字串當然是看作括弧序列啦,(為1,)為-1
我們來分類討論一下:
x>0且y>0 那麼這個字串肯定是分在決策第一類,因為他可以給我們更多的左括弧以便後面匹配
x>0且y<0 不存在的,那不成你x>y?
x<0且y>0 這種字串肯定是分在決策第二類,但若有兩個字串都符合這個規則,則讓x大的先決策,正確性顯然
x<0且y<0 這種情況就有一點點複雜了
我們考慮現在有兩個字串a和b,現在有的左括弧為j
那麼我看考慮,若我們同時想擁有a和b(當然,這個單個放是肯定可以的)
先放a,要滿足的條件為:j+a.y+b.x>0
先放b,要滿足的條件為j+b.y+a.x>0
我們來思考哪一個條件更苛刻,肯定是簡單的一個優先
於是就是要比較
a.y+b.x和b.y+a.x
移項就好了

#include<cstdio>#include<algorithm>#include<iostream>#include<cstring>using namespace std;const int N=305;const int MAX=1<<30;int n;struct qq{    char a[N];    int len;    int x,y;//最小值    總和 }s[N];bool cmp (qq a,qq b)//a是否比b優  換句話說是否不需要交換 {    if (a.y>=0&&b.y<0) return true;    if (b.y>=0&&a.x<0) return false;    if (a.y>=0) return a.x>b.x;    return a.y-a.x>b.y-b.x;}int f[2][100005];int main(){    scanf("%d",&n);    for (int u=1;u<=n;u++)    {        scanf("%s",s[u].a+1);        s[u].len=strlen(s[u].a+1);        int ooo=0;        s[u].x=0;        for (int i=1;i<=s[u].len;i++)        {            if (s[u].a[i]=='(') ooo++;            else ooo--;            s[u].x=min(s[u].x,ooo);        }        s[u].y=ooo;    }    for (int u=1;u<=n;u++)        for (int i=u+1;i<=n;i++)            if (!cmp(s[u],s[i]))                swap(s[u],s[i]);    /*for (int u=1;u<=n;u++)        printf("%d %d %d\n",s[u].x,s[u].y,s[u].len);*/    int now=0;    for (int u=1;u<=90000;u++) f[0][u]=-MAX;    f[0][0]=0;    for (int u=1;u<=n;u++)    {        now^=1;        for (int i=0;i<=90000;i++)            f[now][i]=f[now^1][i];        for (int i=0;i<=90000;i++)            if (i+s[u].x>=0&&i+s[u].y<=90000)//合法就好                 f[now][i+s[u].y]=max(f[now][i+s[u].y],f[now^1][i]+s[u].len);        /*for (int i=0;i<=10;i++) printf("%d ",f[now][i]);        printf("\n");*/    }    printf("%d\n",f[now][0]);    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.