CSU 1855: Shut the Box 狀壓BFS(2011 Mid-Central USA Regional Contest)__狀態壓縮

來源:互聯網
上載者:User

1855: Shut the Box Submit Page    Summary    Time Limit: 1 Sec     Memory Limit: 256 Mb     Submitted: 37     Solved: 9     Description


Shut the Box is a one-player game that begins with a set of N pieces labeled from 1 to N. All pieces are initially "unmarked" (in the picture at right, the unmarked pieces are those in an upward position). In the version we consider, a player is allowed up to T turns, with each turn defined by an independently chosen value V (typically determined by rolling one or more dice). During a turn, the player must designate a set of currently unmarked pieces whose numeric labels add precisely to V, and mark them. The game continues either until the player runs out of turns, or until a single turn when it becomes impossible to find a set of unmarked pieces summing to the designated value V (in which case it and all further turns are forfeited). The goal is to mark as many pieces as possible; marking all pieces is known as "shutting the box." Your goal is to determine the maximum number of pieces that can be marked by a fixed sequence of turns.

As an example, consider a game with 6 pieces and the following sequence of turns: 10, 3, 4, 2. The best outcome for that sequence is to mark a total of four pieces. This can be achieved by using the value 10 to mark the pieces 1+4+5, and then using the value of 3 to mark piece 3. At that point, the game would end as there is no way to precisely use the turn with value 4 (the final turn of value 2 must be forfeited as well). An alternate strategy for achieving the same number of marked pieces would be to use the value 10 to mark four pieces 1+2+3+4, with the game ending on the turn with value 3. But there does not exist any way to mark five or more pieces with that sequence. Input

Each game begins with a line containing two integers, N, T where 1 ≤ N ≤ 22 represents the number of pieces, and 1 ≤ T ≤ N represents the maximum number of turns that will be allowed. The following line contains T integers designating the sequence of turn values for the game; each such value V will satisify 1 ≤ V ≤ 22. You must read that entire sequence from the input, even though a particular game might end on an unsuccessful turn prior to the end of the sequence. The data set ends with a line containing 0 0. Output

You should output a single line for each game, as shown below, reporting the ordinal for the game and the maximum number of pieces that can be marked during that game. Sample Input

6 410 3 4 26 510 2 4 5 310 101 1 3 4 5 6 7 8 9 1022 2222 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 10 0
Sample Output
Game 1: 4Game 2: 6Game 3: 1Game 4: 22

         多校賽第四場,個人認為自己發揮不錯,當場A了這個狀壓。如果不算隊友那個因為環境問題而WA的題,我們應該能排到前五……

        當時在現場敲這題的時候思路不清晰,前後中斷了兩次(寫到一半讓別人先寫其他題),最後總算寫出來了。現在在賽後理清楚思路後半個小時敲出來直接A,事實證明思路清晰、演算法明了比盲目的寫重要啊,雖然最後發現這題並不難~

        這題一看資料範圍22,然後每一個box又只有兩個狀態上和下,順理成章的直接就想到了狀壓。用第i個box對應位元的第i位,1代表該box被摁下去了,0代表該box還未被摁下去。最後我們只需要找1出現最多次的狀態即可。

        第一反應是往dp的方向上想的,枚舉每一個狀態,然後最後找到所有可行的狀態中被摁下去的box的最多數目。然而這樣的話總狀態數1<<22,在加上有22個可以供拆分的數字,時空複雜度瞬間飆升(在這裡我卡了第一次)。接著,我發現很多狀態完全沒有必要去枚舉。初始時只有一個狀態(全為0),往後狀態是一步一步拓展出來的,也就是說,多餘的步驟不需要枚舉,只需要在這些拓展出來的點中繼續轉移即可。這樣就和第二次多校賽的Monkey那題差不多了。利用一個bfs去不斷的拓展狀態,一直到最後無法拓展。對於每一個狀態,能夠轉移的條件是上一個狀態與當前方案的按位與為0,即不存在某個位置使得方案與原狀態都為1,並且要求該狀態並未出現過(剪枝。多餘。)。

        再細化一步,就是對方案的預先處理了(很不要臉的說我在這卡了第二次)。方案的話就是對一個數進行拆分,把所有的拆分方案儲存在一個vector裡面,並且加上一個權值(該方案下增加的1的個數)。這個用簡單的搜尋即可,但是我在第一次寫的時候居然認為可以不用剪枝,結果果斷TLE,按理說即使資料小也要加上這些基礎的剪枝的……搜尋是基礎,具體怎麼剪我就不說了。

        在比賽結束的時候,長理的大佬說這題是個最短路……其實是一樣的嘛,一開始做的事情其實是對每個狀態進行連邊,而那麼方案增加的1的個數就是對應邊的權值,構好圖之後走一遍最長路就是結果,本質上是一樣的,bfs的過程也就是求最長路。最後就上個代碼啦,這是賽後重新寫的版本,比原版本要清晰:

#include<bits/stdc++.h>#define MAXN 23using namespace std;struct node{int ans,x,y;node() {}node(int _x,int _y,int _ans): x(_x),y(_y),ans(_ans){}};vector<int> g[MAXN],sta;deque<node> que;int m,n,w[MAXN][100];bool v[1<<MAXN];inline void dfs(int x,int i,int b){if (!x){int num=0;for(int j=0;j<sta.size();j++)num|=1<<sta[j];w[i][g[i].size()]=sta.size();g[i].push_back(num); return;}if (x<b||b>n) return;sta.push_back(b);dfs(x-b,i,b+1);sta.pop_back();dfs(x,i,b+1);}int main(){int T=0;while (~scanf("%d%d",&n,&m)&&n&&m){for(int i=0;i<n;i++) g[i].clear();memset(w,0,sizeof(w));for(int i=0;i<m;i++){int x; scanf("%d",&x);dfs(x,i,1);}int ans=0;que.clear();memset(v,0,sizeof(v));que.push_back(node(0,0,0));while(!que.empty()){node i=que.front();que.pop_front();for(int j=0;j<g[i.y].size();j++)if ((i.x&g[i.y][j])==0 && !v[i.x|g[i.y][j]]){node k=node(i.x|g[i.y][j],i.y+1,i.ans+w[i.y][j]);que.push_back(k);ans=max(ans,k.ans);v[i.x|g[i.y][j]]=1;}}printf("Game %d: %d\n",++T,ans);}} 

聯繫我們

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