题目描述
设在一排上有N个格子(N≤20),若在格子中放置有不同颜色的灯,每种灯的个数记为N1,N2,……Nk(k表示不同颜色灯的个数)。
放灯时要遵守下列规则:
①同一种颜色的灯不能分开;
②不同颜色的灯之间至少要有一个空位置。
例如:N=8(格子数)
R=2(红灯数)
B=3(蓝灯数)
放置的方法有:
R-B顺序
R | R |
| B | B | B |
|
|
R | R |
|
| B | B | B |
|
R | R |
|
|
| B | B | B |
| R | R |
| B | B | B |
|
| R | R |
|
| B | B | B |
|
| R | R |
| B | B | B |
B-R顺序
B | B | B |
| R | R |
|
|
B | B | B |
|
| R | R |
|
B | B | B |
|
|
| R | R |
| B | B | B |
| R | R |
|
| B | B | B |
|
| R | R |
|
| B | B | B |
| R | R |
放置的总数为12种。
程序要求:求排列总数。
输入格式
数据输入的方式为:
N
P1(颜色,为一个字母) N1(灯的数量)
P2 N2
……
Q(结束标记,Q本身不是灯的颜色)
颜色和灯的数量之间由一个空格分隔。
输出
输出排列总数。
样例输入
8
R 2
B 3
Q
样例输出
12
注意同意颜色归到一起
暴力搜索出一种颜色顺序下的所有顺序
再将它乘上N种颜色的排列数N!
即可得到总排列数。。。。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
struct color{ //没必要用结构体 开始想复杂了 数组就OK
char aa;
int bb;
}q[10];
int num=0,s;
int sss=0; //同意颜色顺序下排序数
void dfs(int a,int b,int c) //a表示已用颜色 b表示已放格子数 c表示是否要放空格
{
if(a==num&&b==s)
{
sss++;
return;
}
if(b>s)
return;
if(c!=1)
dfs(a+1,b+q[a].bb,1);
dfs(a,b+1,0);
}
int main()
{
int i,j;
int sum;
int ss=0;
char a;
int b;
scanf("%d",&s);
while(cin>>a&&a!='Q')
{
scanf("%d",&b);
ss=ss+b;
int t=0;
for(i=0;i<num;i++)
{
if(q[i].aa==a)
{
q[i].bb+=b;
t=1;
}
}
if(t==0)
{
q[num].aa=a;
q[num++].bb=b;
}
}
int per=1;
for(i=1;i<=num;i++)
per=per*i;
if(s-ss-num+1<=0) //格子不够
cout<<0<<endl;
else
{
dfs(0,0,0);
cout<<sss*per<<endl;
}
return 0;
}