解题思路:
我们先考虑小朋友不交换的情况,仅仅考虑1 2 怎么排能正好找完钱,设1元为a,2元为b:
3a2b的情况下:设A=3 B=2
aaabb aabba aabab abaab ababa
而不能 abbaa·····
可以看出能排b在n+1个位置的时候只能是:
(a的数目-b的数目>=0)===>(A-剩下a的数目)-(B-剩下b的数目)>=0
所以这个条件要作为递归的一个退出条件。
当我们排列完了所有数字后,即可+1
OK
现在我们要解决一种情况(状态)下有多少种排列的问题 还是上面的例子 将1元替换成小写,2元为大写。
我们只需要考虑一种状态就行了 aaabb
abcAB abcBA
acb····· ·······BA
bac····· ·······BA
bca····· ·······BA
cab····· ·······BA
cba····· ·······BA
可以看出来 小写字母,按行看遵循的是A!,大写字母,按列看遵循的是B! 所以
一种状态下的所有排列p=A!*B!
根据以上理论我们可以编写我们的递归代码了
注意事项:
参考代码:
#include <iostream>
#include <math.h>
using namespace std;
int k=0,ONE,TWO,p;//ONE TWO 是1元 2元的人数 k(只考虑钱该怎么摆放,而不考虑交换的情况的"状态")
void fun(int n,int o,int t){//o为1元人数还剩多少 同理t为2元人数剩多少 n代表剩几个人
if(( (ONE-o)-(TWO-t) ) <0 )return;
if(n==0){
k+=p;
return;
}
if(o!=0)fun(n-1,o-1,t);
if(t!=0)fun(n-1,o,t-1);
}
int main(){
int one,two,n,
a=1,b=1;//a b 求阶乘 p为a*b 代表一种排队"状态"成功下,有p种排列
cin>>n>>one>>two;
ONE=one;TWO=two;
for(int i=0;i<one;i++)a*=(one-i);
for(int i=0;i<two;i++)b*=(two-i);
p=a*b;//一种状态下有多少种排列方式
fun(n,one,two);
cout<<k<<endl;
return 0;
}
0.0分
1 人评分
2^k进制数 (C语言描述,蓝桥杯)浏览:1420 |
1048题解(读入回车问题)浏览:554 |
C语言程序设计教程(第三版)课后习题11.3 (C语言代码)浏览:564 |
C语言程序设计教程(第三版)课后习题8.4 (C语言代码)浏览:565 |
求圆的面积 (C语言代码)浏览:657 |
C语言程序设计教程(第三版)课后习题5.5 (C语言代码)浏览:446 |
C语言训练-求矩阵的两对角线上的元素之和 (C语言代码)浏览:926 |
C语言程序设计教程(第三版)课后习题6.4 (C语言代码)浏览:442 |
C语言程序设计教程(第三版)课后习题9.6 (C语言代码)浏览:2739 |
C语言程序设计教程(第三版)课后习题7.2 (C语言代码)浏览:480 |