组合数和排列数

输出组合数和排列数

#include<stdio.h>
typedef long long LL;
LL factorial(int num){
	LL mul;
	if (num==0) mul=1;
	else mul=num*factorial(num-1);
	return mul;
}
void cp_mn(int m,int n, LL a[]){
	a[1]=factorial(m)/factorial(n)/factorial(m-n);//A(n,m)=n(n-1)(n-2)……(n-m+1)= n!/(n-m)!
	a[2]=factorial(m)/factorial(m-n);			//C(n,m)=A(n,m)/m!=n!/((n-m)!*m!);
}
int main(){
	int a,b;
    LL cp[2];
	printf("input 2 numbers:\n");
	scanf("%d %d",&a,&b);
	cp_mn(a,b,cp);
	printf(" 组合数: %ld,排列数 %ld\n",cp[1],cp[2]);//组合数认为(1,2)和(2,1)是同样的组合
}

计算组合数
题目描述
计算组合数。C(n,m),表示从n个数中选择m个的组合数。计算公式如下:
C(n,m) = C(n-1,m-1) + C(n-1,m).
输入
第一行是正整数N,表示有N组要求的组合数。接下来N行,每行两个整数n,m (0 <= m <= n <= 20)。
输出
输出N行。每行输出一个整数表示C(n,m)。

#include<stdio.h>
int sum(int n,int m) {
 	if(m==0||n==1||m==n) return 1;
	else return sum(n-1,m-1)+sum(n-1,m);
}
int main() {
	int N;
	scanf("%d",&N);
	while(N--) {
		int n,m;
		scanf("%d %d",&n,&m);
		printf("%.0d\n",sum(n,m));  
	}
	return 0;
}

解法2

#include<stdio.h>  
double fac(int k)  {  
	double mul=0; 
    if (k==0) mul=1;
	else mul=k*fac(k-1);
    return mul;  
}  
double cmn(int m,int n)  {  
    double res;  
    res=fac(m)/(fac(n)*fac(m-n));  
    return res;  
}  
void main()  {  
    int m,n,i,b;  
    double t;  
    scanf("%d",&b);  
    for(i=0;i<b;i++)  {  
	    scanf("%d %d",&m,&n);  
	    t=cmn(m,n);  
	    printf("%.0lf\n",t);  
	}  
}

### 完全背包问题中的组合数排列数 #### 组合数计算方法 对于完全背包问题,在求解组合数时,关注的是不同的物品集合能够组成目标值的方式数量。这里的关键在于理解每个物品可以选择多次使用。 定义 `dp[i][j]` 表示从前 i 种物品中选取若干件(每种可选无限次),使得其价值恰好等于 j 的方案总数。状态转移方程如下: 当不考虑第 i 个物品时,继承之前的状态;当考虑第 i 个物品时,则加上选择了该物品后的剩余容量所能形成的方案数目[^1]。 ```python def combination_count(weights, target): n = len(weights) dp = [[0]*(target+1) for _ in range(n+1)] # 初始化:只有重量为0的情况有一种方式即什么都不取 for i in range(n+1): dp[i][0] = 1 for i in range(1, n+1): for w in range(target+1): if weights[i-1] <= w: dp[i][w] = dp[i-1][w] + dp[i][w-weights[i-1]] else: dp[i][w] = dp[i-1][w] return dp[n][target] ``` #### 排列数计算方法 不同于组合数只关心哪些物品被选用而不顾顺序,排列数还需要考虑到这些选定物品之间的不同排序情况。因此,在处理排列数时,需要调整遍历顺序来体现这一点。 具体来说,为了得到排列的结果,应该先遍历背包容量再遍历物品列表。这样做的原因是让每一个新的容量都尝试加入当前已有的所有可能路径上[^3]。 ```python def permutation_count(weights, target): n = len(weights) dp = [0] * (target + 1) dp[0] = 1 # 当总重为0时有唯一解为空集 for w in range(1, target+1): for weight in weights: if w >= weight: dp[w] += dp[w-weight] return dp[target] ``` 通过上述两种算法实现可以看出,虽然两者都是基于动态规划的思想解决完全背包问题的不同变体,但在细节上的差异决定了最终解决问题的角度——是单纯统计满足条件的子集还是进一步区分它们内部元素间的相对位置关系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值