题目描述
设在一排上有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; }
时间: 2024-10-18 08:15:14