IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 多重集组合数【dp】 -> 正文阅读

[数据结构与算法]多重集组合数【dp】

原题链接

题面

在这里插入图片描述

思路

首先用过题意可以很容易想到一个三重循环的解决方法:

  • 代码是:

    #include<bits/stdc++.h> 
    using namespace std;
    const int N = 1e3 + 10;
    int a[N], f[N][N];
    int main()
    {
    	int n, m, M;
    	cin >> n >> m >> M;
    	for (int i = 1; i <= n; i ++ ) cin >> a[i];
    	f[0][0] = 1;
    	for (int i = 1; i <= n; i ++ )
    	{
    		for (int j = 0; j <= m; j ++ )
    		{
    			for (int k = 0; k <= min(j, a[i]); k ++ )
    			{
    				f[i][j] = f[i][j] + f[i - 1][j - k];
    				f[i][j] %= M;
    			}
    		}
    	}
    	cout << f[n][m] << endl;
    	return 0;
    }
    

    意思是对于第i种物品,选j件时的方案数,可以由不选这件物品时 少用 k k k 件时的方案数得来

  • 定义 f i j f_{ij} fij? 是前 i i i 种物品选 j j j 个的方案数

  • j = = 0 j == 0 j==0 f i j = f ( i ? 1 ) j f_{ij} = f_{(i - 1)j} fij?=f(i?1)j?

  • 1 < = j < = k 1 <= j <= k 1<=j<=k

    • f i j = f ( i ? 1 ) ( j ? 0 ) + f ( i ? 1 ) ( j ? 1 ) + … + f ( i ? 1 ) ( j ? j ) f_{ij} = f{(i - 1)(j - 0)} + f{(i - 1)(j - 1)} + … + f{(i - 1)(j - j)} fij?=f(i?1)(j?0)+f(i?1)(j?1)++f(i?1)(j?j)

    • f i ( j ? 1 ) = f ( i ? 1 ) ( j ? 1 ) + f ( i ? 1 ) ( j ? 2 ) + … + f ( i ? 1 ) ( j ? j ) f_{i(j - 1)} = f{(i - 1)(j - 1)} + f{(i - 1)(j - 2)} + … + f{(i - 1)(j - j)} fi(j?1)?=f(i?1)(j?1)+f(i?1)(j?2)++f(i?1)(j?j)

    • 移项得

      f i j = f ( i ? 1 ) j + f i ( j ? 1 ) f_{ij} = f_{(i - 1)j} + f_{i(j - 1)} fij?=f(i?1)j?+fi(j?1)?

  • k < j k < j k<j :(这里一位是多减了一个,但又因为是大于,所以顶多减成0,不会越界)

    • f i j = f ( i ? 1 ) ( j ? 0 ) + f ( i ? 1 ) ( j ? 1 ) + … + f ( i ? 1 ) ( j ? k ) f_{ij} = f_{(i - 1)(j - 0)} + f_{(i - 1)(j - 1)} + … + f_{(i - 1)(j - k)} fij?=f(i?1)(j?0)?+f(i?1)(j?1)?++f(i?1)(j?k)?

    • f i ( j ? 1 ) = f ( i ? 1 ) ( j ? 1 ) + f ( i ? 1 ) ( j ? 2 ) + … + f ( i ? 1 ) ( j ? k ) + f ( i ? 1 ) ( j ? k ? 1 ) f_{i(j - 1)} = f_{(i - 1)(j - 1)} + f_{(i - 1)(j - 2)} + … + f_{(i - 1)(j - k)} + f_{(i - 1)(j - k - 1)} fi(j?1)?=f(i?1)(j?1)?+f(i?1)(j?2)?++f(i?1)(j?k)?+f(i?1)(j?k?1)?

    • 移项得

      f i j = f ( i ? 1 ) ( j ) + f ( i ? 1 ) ( j ? 2 ) ? f ( i ? 1 ) ( j ? k ? 1 ) + f i ( j ? 1 ) f_{ij} = f_{(i - 1)(j)} + f_{(i - 1)(j - 2)} - f_{(i - 1)(j - k - 1)} + f_{i(j - 1)} fij?=f(i?1)(j)?+f(i?1)(j?2)??f(i?1)(j?k?1)?+fi(j?1)?

  • 最终得到两重循环的代码

    #include<bits/stdc++.h> 
    using namespace std;
    const int N = 1e3 + 10;
    int a[N], f[N][N];
    int main()
    {
    	int n, m, M;
    	cin >> n >> m >> M;
    	for (int i = 1; i <= n; i ++ ) cin >> a[i];
    	f[0][0] = 1;
    	for (int i = 1; i <= n; i ++ )
    	{
    		for (int j = 0; j <= m; j ++ )
    		{
    			if (j == 0) f[i][j] += f[i - 1][j];
    			else if (1 <= j && j <= a[i]) f[i][j] += (f[i - 1][j] + f[i][j - 1]);
    			else if (j > a[i]) f[i][j] += (f[i - 1][j] + f[i][j - 1] - f[i - 1][j - 1 - a[i]]);
    			f[i][j] = (f[i][j] + M) % M;
    		}
    	}
    	cout << f[n][m] << endl;
    	return 0;
    }
    
  • 注意点,在运算中包含减法,取模时,需要先加上余数再取模,不然有可能变成负数

  • 参考

  • 在这里插入图片描述

总结

当时写的时候应该是懂了没错,可是现在补题解的时候却又觉得有些一知半解,需要多多复习。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-03 16:39:43  更:2022-03-03 16:40:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 15:25:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码