排列组合
作者:互联网
数学题
n个人参加ACM比赛。比赛有n道题目,裁判程序根据选手解正确的题数评名次,可以有并列名次。问有多少种可能的获奖方案?
输入格式
第一行1个正整数n, 0<n<16
输出格式
方案数。
输入:
4
输出:
75
思路:
1.递推
2.暴搜+全排列
超时代码:
#include<iostream>
#include<fstream>
#include<algorithm>
#include<cmath>
#include<string>
#include<map>
using namespace std;
int n,sum,a[15];
bool check()
{
int f[15]={0},k=0;
for(int i=1;i<=n;i++)
f[a[i]]++,k=max(k,a[i]);
for(int i=1;i<=k;i++)
if(f[i]==0) return 0;
return 1;
}
void dfs(int w)
{
if(w==n+1)
{
if(check()==1)
sum++;
return;
}
for(int i=1;i<=n;i++)
{
a[w]=i;
dfs(w+1);
}
}
int main()
{
cin>>n;
dfs(1);
cout<<sum<<endl;
return 0;
}
很明显,这个代码没有任何优化(朴实无华)
So,就超时了
那么让我们思考思考~
哈!
1.递推
代码:
#include<iostream>
#include<fstream>
#include<algorithm>
#include<cmath>
#include<string>
#include<iomanip>
using namespace std;
int f[20],n;
int C(int n,int k)//组合
{
int s=1;
for(int i=1;i<=k;i++)
{
s=s*n;
n--;
}
int d=1;
for(int i=1;i<=k;i++)
d=d*i;
return s/d;
}
int main()
{
cin>>n;
f[0]=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=i;j++)
{
f[i]=f[i]+f[i-j]*C(i,j);//从i个里取j个
}
}
cout<<f[n];
return 0;
}
递推式: ![f[i]=f[i]+f[i-j]*C(i,j);](https://latex.codecogs.com/gif.latex?f%5Bi%5D%3Df%5Bi%5D+f%5Bi-j%5D*C%28i%2Cj%29%3B)
i 个人,有 j 个"1" ,剩下 i-j 个人,(名次同时进一名),i-j 个人有多少种方案已经求出,乘上 C(i,j) 便是 “ i 个人,有 j 个"1"” 的答案
标签:名次,个人,int,using,排列组合,include,递推 来源: https://blog.csdn.net/yyh0910/article/details/116835376