首页 > 编程语言 >225. 多重集组合数(挑战程序设计竞赛)

225. 多重集组合数(挑战程序设计竞赛)

时间:2023-01-10 11:33:07浏览次数:62  
标签:ai 多重集 int 物品 程序设计 225 dp 1000

地址 https://www.papamelon.com/problem/225

有 n 种物品,第i 种物品有 a_i个。
不同种类的物品可以互相区分但相同种类的无法区分。从这些物品中取出 m 个物品的话,有多少种取法?

求出方案数模 M 的余数。

输入
输入第一行有三个整数n、m、M, 第二行有n个整数,表示数组a_i
1≤n≤1000
1≤m≤1000
1≤ai≤1000
2≤M≤10000
输出
输出一个整数,表示方案数模 M 的余数
样例 1
输入
3 3 10000
1 2 3
输出
6

解法
动态规划优化
dp[i][j] 表示前i组取出j个的方案数目
还要根据j和ai的数目分开讨论
j <= ai
(1) dp[i][j] = dp[i-1][j] + dp[i-1][j-1]~~~~dp[i-1][0]

j > ai
(2) dp[i][j] = dp[i-1][j] + dp[i-1][j-1]~~~~dp[i-1][j-ai]

同样的 dp[i][j-1] 也能得到两个状态转移 并且可以和上面的式子进行优化

j <= ai
(3) dp[i][j-1] = dp[i-1][j-1]+dp[i-1][j-2]~~~~dp[i-1][0]

j > ai
(4) dp[i][j-1] = dp[i-1][j-1] + dp[i-1][j-2]~~~~dp[i-1][j-ai]+dp[i-1][j-1-ai]

(1)和(3)可以优化
dp[i][j] - dp[i][j-1] = dp[i-1][j];

(2)和(4)可以优化
dp[i][j] - dp[i][j-1] = dp[i-1][j] - dp[i-1][j-1-ai];

综合所得 状态转移公式
j <= ai
dp[i][j] = dp[i-1][j] + dp[i][j-1]

j > ai
dp[i][j] = dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1-ai]

得到状态转移公式就得到了流程
代码如下

#include <iostream>

using namespace std;
const int N = 1010;
int n, m, M;
int a[N];
int dp[N][N];

int main()
{
	cin >> n >> m >> M;
	for (int i = 1; i <= n; i++) cin >> a[i];
	
	for (int i = 0; i <= n; i++) { dp[i][0] = 1; }


	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			if (j >= 1 && j <= a[i]) {
				dp[i][j] = dp[i][j - 1] + dp[i - 1][j];
			}
			else {
				dp[i][j] = dp[i][j - 1] + dp[i - 1][j] - dp[i - 1][j - 1 - a[i]];
			}
			dp[i][j] = (dp[i][j]+M) % M;
		}
	}

	cout << dp[n][m] << endl;

	return 0;
}

我的视频题解空间

标签:ai,多重集,int,物品,程序设计,225,dp,1000
From: https://www.cnblogs.com/itdef/p/17039664.html

相关文章

  • 面向对象程序设计 第二章 C++简单的程序设计
    目录C++语言的特点1.兼容C语言·它保持了C的简洁、高效和接近汇编语言等特点。·对C的类型系统进行了改革和扩充。·C++也支持面向过程的程序设计,不是一个纯正的面......
  • 224. 划分数(挑战程序设计竞赛)
    地址https://www.papamelon.com/problem/224有n个无区别的物品,将它们划分成不超过m组,求划分方法数模M的余数输入输入第一行有三个整数n、m、M1≤m≤n≤100......
  • 刷刷刷 Day 10 | 225. 用队列实现栈
    225.用队列实现栈LeetCode题目要求请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop和empty)。实现MyStack类:voidpush(int......
  • leetcode-225-easy
    ImplementStackusingQueuesImplementalast-in-first-out(LIFO)stackusingonlytwoqueues.Theimplementedstackshouldsupportallthefunctionsofanorm......
  • 223. 最长上升子序列问题(挑战程序设计竞赛)
    地址https://www.papamelon.com/problem/223有一个长为n的序列a_0,a_1,...,a_n。求出这个序列的最长上升子序列的长度。上升子序列指的是对于任意的i<j都满足......
  • 222. 多重部分和问题(挑战程序设计竞赛)
    地址https://www.papamelon.com/problem/222有n种不同大小的数字a_i,每种各m_i个。判断是否可以从这些数字之中选出若干个并使得它们的和恰好为K输入第一行包含......
  • C++面向对象程序设计
    目录第二章类和对象构造函数析构函数对象数组第三章深入理解类和对象3.5常对象与常成员3.6动态创建对象和释放对象3.7对象的生存期3.8程序实例第四章静态成员与友元......
  • 2022-2023-1 20221320 《计算机基础与程序设计》第十九周学习总结
    学期(2022-2023-1)学号(20221320)《计算机基础与程序设计》第十九周学习总结作业信息各项要求具体内容<班级的链接>2022-2023-1-计算机基础与程序设计<作业要......
  • CodeForces - 1225C p-binary
    CodeForces-1225Cp-binary题解:二进制+思维由题意得:让我们求出K的最小值使得\(\sum_{i=1}^{k}2^{a^i}+p=n\)成立,将式子改变一下形式得到\(n-k*p=\sum_{i=1}^{k}2^......
  • 面向对象程序设计 第一章 绪论
    第一章绪论目录·计算机程序设计语言的发展·面向对象的方法·面向对象的软件开发·程序开发的过程·信息的表示与存储计算机程序·计算机的工作使用程序......