特别好的题解:https://blog.dotcpp.com/Tianxn/59931
机器人塔
X星球的机器人表演拉拉队有两种服装,A和B。
他们这次表演的是搭机器人塔。
类似:
A
B B
A B A
A A B B
B B B A B
A B A B B A
队内的组塔规则是:
A 只能站在 AA 或 BB 的肩上。
B 只能站在 AB 或 BA 的肩上。
你的任务是帮助拉拉队计算一下,在给定A与B的人数时,可以组成多少种花样的塔。
输入一行两个整数 M 和 N,空格分开(0<M,N<500),分别表示A、B的人数,保证人数合理性。
要求输出一个整数,表示可以产生的花样种数。
例如:
用户输入:
1 2
程序应该输出:
3
再例如:
用户输入:
3 3
程序应该输出:
4
资源约定:
峰值内存消耗 < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型。
#include<stdio.h>
//A用0表示 ,b用1表示 ,这样的话由下一层到上一层 可以用异或来表示上一层的。
int n,m;
int x=1;
int pur[600][600];
long long ans=0;
int cnt=0;//表示B的个数
void dfs(int cur)
{
if(cnt>n||cur*(cur+1)/2-cnt>m) return;//这里注意cur*(cur+1)/2为当前A和B的总个数
if(cur==x)
{
ans++;
return ;
}
for(int i=0;i<2;i++)
{
pur[0][cur]=i;
cnt+=i;
for(int j=1;j<=cur;j++)
{
pur[j][cur-j]=pur[j-1][cur-j]^pur[j-1][cur-j+1];
cnt+=pur[j][cur-j];
}
dfs(cur+1);
for(int j=1;j<=cur;j++)
{
cnt-=pur[j][cur-j];//回溯
}
cnt-=i;//回溯
}
}
int main()
{
scanf("%d%d",&m,&n);
while(x*(x+1)/2!=m+n) x++;
dfs(0);
printf("%lld\n",ans);
return 0;
}