当前位置:首页 > 入门组 > 洛谷P1077题(2012年NOIP普及组):用动态规划解决摆花问题

洛谷P1077题(2012年NOIP普及组):用动态规划解决摆花问题

4个月前 (08-11)

洛谷P1077题(2012年NOIP普及组):用动态规划解决摆花问题 洛谷题解 动态规划 背包问题 状态转移方程 NOIP 普及组 递推 第1张

一、题目解读

洛谷P1077题目要求计算在给定n种花和m盆的情况下,满足每种花数量不超过其限制条件时,总共有多少种不同的摆放方案。题目本质是一个经典的组合数学问题,需通过合理的算法设计来高效求解。

二、解题思路

观察到题目中每种花的数量存在上限,且总盆数固定,此类问题常与动态规划中的“背包问题”思路关联。关键在于设计状态转移方程:用dp[i][j]表示前i种花摆放j盆的方案数。通过枚举第i种花的摆放数量,结合前i-1种花的方案,推导出当前状态的可能组合。

三、解题步骤

1. 初始化:定义dp数组,前i种花不摆放(j=0)的方案数为1(即空集)。

2. 状态转移:外层循环遍历花种类i,内层循环遍历总盆数j,并枚举第i种花的摆放数量k(0~min(a[i],j))。

3. 核心逻辑:dp[i][j] += dp[i-1][j-k],即当前方案数等于不选第i种花(dp[i-1][j])与选择k盆第i种花(dp[i-1][j-k])的方案数之和,取模避免溢出。

4. 结果输出:最终dp[n][m]即为所求方案总数。

四、代码与注释

#include <iostream>  
#include <vector>  
using namespace std;  

const int MOD = 1e6 + 7;  

int main() {  
    ios::sync_with_stdio(false);  
    cin.tie(nullptr); // 加快输入输出速度  

    int n, m;  
    cin >> n >> m;  
    vector<int> a(n + 1); // 花的数量限制,从1开始编号  
    for (int i = 1; i <= n; ++i) {  
        cin >> a[i];  
    }  

    // dp[i][j]表示前i种花摆放j盆的方案数  
    vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0));  

    // 初始化:前i种花摆放0盆的方案数为1(什么都不放)  
    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) {  
            // 第i种花可以放0到min(a[i],j)盆  
            for (int k = 0; k <= a[i] && k <= j; ++k) {  
                dp[i][j] = (dp[i][j] + dp[i - 1][j - k]) % MOD;  
            }  
        }  
    }  

    cout << dp[n][m] << endl;  
    return 0;  
}

注释说明:通过动态规划递推,利用状态转移方程优化计算,避免重复组合,确保结果正确且高效。

五、总结

洛谷P1077通过动态规划将组合问题转化为状态转移的求解,核心在于理解“前缀和”与“局部选择”的关系。合理设计dp数组和边界条件,能有效降低时间复杂度。在实际应用中,此类思路可扩展至多约束条件的组合优化场景。


原创内容 转载请注明出处

分享给朋友:

相关文章

力扣198.打家劫舍|动态规划解法中的特殊边界处理

力扣198.打家劫舍|动态规划解法中的特殊边界处理

题意解析:在排列成直线的房屋群中,每个房屋藏有价值不同的财物。小偷不能连续抢劫相邻的两间房屋,否则会触发警报。我们需要设计一套抢劫策略,使得在不触发警报的前提下,能够获取的最大财物总和。这个问题本质上...

CSP-J方格取数题解|动态规划解法|洛谷P7074代码解析

CSP-J方格取数题解|动态规划解法|洛谷P7074代码解析

一、题目解读题目要求在一个n×m的网格中,从左上角到右下角选择一条路径,路径上的数字可重复取用,求取数之和的最大值。路径限制为仅能向右或向下移动。需注意路径的灵活性与重复取数的可能性,传统单向动态规划...

牛客12576题解题全解析:动态规划+质因数分解实现跳跃问题最优解

牛客12576题解题全解析:动态规划+质因数分解实现跳跃问题最优解

一、题目解读牛客12576题是一道经典的算法题,要求给定起点N和终点M,求解从N到M的最少跳跃次数。题目考察的核心在于路径优化与动态规划思想,需结合数论中的质因数分解技巧,通过合理设计算法降低时间复杂...

CSP-J 2019公交换乘题解析:基于队列优化的动态规划代码详解

CSP-J 2019公交换乘题解析:基于队列优化的动态规划代码详解

一、题目解读CSP-J 2019年的“公交换乘”题目(洛谷P5661)要求模拟地铁与公交交替出行的费用计算。题目核心在于地铁消费会产生优惠券,而公交可在45分钟内使用优惠券抵扣车费。需要处理n条出行记...

洛谷P4999题解析:动态规划求解数字拆分与求和问题(附代码)

洛谷P4999题解析:动态规划求解数字拆分与求和问题(附代码)

一、题目解读洛谷P4999题要求处理给定区间 [L, R] 内数字的拆分与求和问题。每个数字需拆分为其各位数字之和,并计算区间内所有数字之和的累加结果。题目需考虑大数情况,并采用取模运算(MOD=1e...

2022 CSP-J 上升点序(洛谷P8816)解题报告:动态规划求解最长上升序列

2022 CSP-J 上升点序(洛谷P8816)解题报告:动态规划求解最长上升序列

一、题目解读2022年CSP-J题目“上升点序”(洛谷P8816)要求给定一个平面点集,每个点的坐标(x,y)均为整数。题目需要构造一个最长的上升序列,序列中相邻点的坐标满足x和y均严格递增。允许使用...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。