每日一题 多重集组合数

多重集组合数 (来源:《挑战程序设计竞赛》)

n种物品, 第i种物品有ai个. 不同种类的物品可以互相区分, 但相同种类的无法区分.

从这些物品中取出m个, 有多少种取法?

例如: 有n=3种物品, 每种a={1,2,3}个, 取出m=3个, 取法result=6(0+0+3, 0+1+2, 0+2+1, 1+0+2, 1+1+1, 1+2+0).

输入:

3 3
1 2 3

输出:

6

分析见注释:

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1010;
int dp[N][N]; //dp[i][j]:前i种物品选j个的选法数量
int a[N];
int n, m;
int main()
{
	cin >> n >> m ;
	for (int i = 1;i <= n;i++) cin >> a[i];

	for (int i = 0;i <= n;i++) dp[i][0] = 1; //i种物品选0个都是只有一种选法
	for (int i = 1;i <= n;i++)
	{
		for (int j = 1;j <= m;j++)
		{
			/*for (int k = 0;k <= a[i];k++) //第i种物品选k个
			{
				dp[i][j] += dp[i-1][j - k];
			}
			推导:dp[i][j]=d[i-1][j]+dp[i-1][j-1]+dp[i-1][j-2]+...+dp[i][j-(a-1)]+dp[i][j-a]                 ①
				  dp[i][j-1]=        dp[i-1][j-1]+dp[i-1][j-2]+...+dp[i][j-(a-1)]+dp[i][j-a]+dp[i][j-a-1]    ②

				  ①式-②式,得  dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1 - a[i]]
			*/
			dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1 - a[i]]; //等效公式
		}
	}
	cout << dp[n][m] << endl;
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值