bzoj2064: 分裂(狀壓dp)

來源:互聯網
上載者:User

標籤:bsp   define   names   har   sdi   狀態   tmp   lag   最大值   

Description背景: 和久必分,分久必和。。。 題目描述: 中國歷史上上分分和和次數非常多。。通讀中國歷史的WJMZBMR表示毫無壓力。 同時經常搞OI的他把這個變成了一個數學模型。 假設中國的國土總和是不變的。 每個國家都可以用他的國土面積代替, 又兩種可能,一種是兩個國家合并為1個,那麼新國家的面積為兩者之和。 一種是一個國家分裂為2個,那麼2個新國家的面積之和為原國家的面積。 WJMZBMR現在知道了很遙遠的過去中國的狀態,又知道了中國現在的狀態,想知道至少要幾次操作(分裂和合并各算一次操作),能讓中國從當時狀態到達現在的狀態。Input第一行一個數n1,表示當時的塊數,接下來n1個數分別表示各塊的面積。 第二行一個數n2,表示現在的塊,接下來n2個數分別表示各塊的面積。Output一行一個數表示最小次數。Sample Input1 6
3 1 2 3
Sample Output2
資料範圍:
對於100%的資料,n1,n2<=10,每個數<=50
對於30%的資料,n1,n2<=6,  這狀壓的思路真是神仙啊……首先,最壞的情況就是把上面的合成一堆,然後再分成下面的,於是次數為$n+m-2$然後考慮如何減少次數。如果上面的可以被合成2塊,下面的也可以合成2塊,且上下兩塊的值分別相等,那麼就可以減少一次合并和一次分開,總次數減少了2於是發現如果上下可以被分成值相等的$k$塊,那麼總的次數是$n+m-2*k$然後現在就是要求$k$的最大值了我們用二進位表示某一個數選或不選。如果一個數是上面的,令它值為正,下面的則值為負然後如果上面的一塊和下面的一塊值對應相等的話,就是所有的值加起來為0這樣如果某一個子集的和為0,就說明它可以互相變化於是令$dp[i]$表示選的狀態為$i$時的最大的$k$,因為只有在$sum[i]==0$時,$dp[i]++$,其他狀態都只能直接轉移
 1 //minamoto 2 #include<bits/stdc++.h> 3 using namespace std; 4 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 5 char buf[1<<21],*p1=buf,*p2=buf; 6 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;} 7 inline int read(){ 8     #define num ch-‘0‘ 9     char ch;bool flag=0;int res;10     while(!isdigit(ch=getc()))11     (ch==‘-‘)&&(flag=true);12     for(res=num;isdigit(ch=getc());res=res*10+num);13     (flag)&&(res=-res);14     #undef num15     return res;16 }17 const int N=2e6+5;18 int n,m,sum[N],dp[N],lim;19 int main(){20 //    freopen("testdata.in","r",stdin);21     n=read();for(int i=1;i<=n;++i) sum[1<<(i-1)]=read();22     m=read();for(int i=1;i<=m;++i) sum[1<<(i+n-1)]=-read();23     lim=1<<(n+m);24     for(int i=1;i<lim;++i){25         int tmp=i&-i;sum[i]=sum[tmp]+sum[i-tmp];26         for(int j=1;j<=n+m;++j)27         if(i&(1<<(j-1))) cmax(dp[i],dp[i-(1<<(j-1))]);28         if(!sum[i]) ++dp[i];29     }30     printf("%d\n",n+m-2*dp[lim-1]);31     return 0;32 }

 

bzoj2064: 分裂(狀壓dp)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.