機器人塔ios
X星球的機器人表演拉拉隊有兩種服裝,A和B。
他們此次表演的是搭機器人塔。數組
相似:函數
A
B B
A B A
A A B B
B B B A B
A B A B B Aspa
隊內的組塔規則是:
A 只能站在 AA 或 BB 的肩上。
B 只能站在 AB 或 BA 的肩上。操作系統
你的任務是幫助拉拉隊計算一下,在給定A與B的人數時,能夠組成多少種花樣的塔。調試
輸入一行兩個整數 M 和 N,空格分開(0<M,N<500),分別表示A、B的人數,保證人數合理性。blog
要求輸出一個整數,表示能夠產生的花樣種數。內存
例如:
用戶輸入:
1 2ci
程序應該輸出:
3資源
再例如:
用戶輸入:
3 3
程序應該輸出:
4
資源約定:
峯值內存消耗 < 256M
CPU消耗 < 1000ms
請嚴格按要求輸出,不要多此一舉地打印相似:「請您輸入...」 的多餘內容。
全部代碼放在同一個源文件中,調試經過後,拷貝提交該源碼。
注意: main函數須要返回0
注意: 只使用ANSI C/ANSI C++ 標準,不要調用依賴於編譯環境或操做系統的特殊函數。
注意: 全部依賴的函數必須明確地在源文件中 #include <xxx>, 不能經過工程設置而省略經常使用頭文件。
提交時,注意選擇所指望的編譯器類型。
這道題確實有點噁心,開始想了好多辦法都錯了。。。。好比列舉底層全排列,顯然有重有漏。底層dp基本沒結果。
不過能夠肯定,不管是從底層開始該排列惟一。從頂層開始則爲DFS,這裏不進行證實!
說一下思路,頂層開始每個位置都是 A或者B,嘗試AB推導法則:
仔細觀察,每層第i個和上層第i個有異或運算A^B=B ,A^A=A,B^B=A,B^A=B。 好了,本題基本結束。
map[line][i]=map[line][i-1]^map[line-1][i-1];
解題時間(2.5hour)
//代碼思路
//0表A,1表B,存在二維數組map中,進行DFS
//每一行的上層肯定而且每行第一個數字肯定,該行惟一
//因此本題就是DFS每行第一個
//題意,A和B的總數cnt<999,設一共能夠擺n行,等差數列求和 cnt=n*n(n+1)/2
//獲得n最大爲44
不懂再問,下面給出代碼:
#include<iostream> #include<algorithm> #include<cmath> #include<cstring> #include<set> #include<stdio.h> #define ll long long using namespace std; int ans; int map[50][50]; void DFS(int line,int re_A,int re_B,int n) //line 當前行 re_A 可用的A re_B 可用的B n表明層數 { int A=re_A; int B=re_B; if(re_A<0||re_B<0) return; if(line == n&&A==0&&B==0) { ans++; return; } re_A=A; re_B=B; map[line][0]=0; re_A-=1; for(int i=1;i<=line;i++) { map[line][i]=map[line][i-1]^map[line-1][i-1]; if(map[line][i]==0){ re_A--; } else{ re_B--; } } DFS(line+1,re_A,re_B,n); re_A=A; re_B=B; map[line][0]=1; re_B-=1; for(int i=1;i<=line;i++) { map[line][i]=map[line][i-1]^map[line-1][i-1]; if(map[line][i]==0) re_A--; else re_B--; } DFS(line+1,re_A,re_B,n); } int main() { int x,y,n; while(cin>>x>>y) { ans=0; for(int i=1;;i++) { if(2*x+2*y==i*i+i) { n=i; break; } } DFS(0,x,y,n); cout<<ans<<endl; } }