完全背包求方案总数

洛谷 P1832 A+B Problem(再升级)

给定一个正整数n,求将其分解成若干个素数之和的方案总数。

这题和P1164 小A点菜很像,但是那题是01背包,这题是完全背包。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#define int long long

using namespace std;

const int maxn = 1e3 + 5;

int dp[maxn][maxn], prime[maxn], book[maxn];

### 完全背包问题在销售场景中的应用 完全背包问题是动态规划领域的一个经典问题,其中每个物品可以被无限次选取。这种特性非常适合用于模拟某些实际生活中的销售场景,比如商品促销活动、批量折扣购买等。 #### 动态规划的核心思想 对于完全背包问题,核心在于如何通过状态转移方程计算最优解。假设我们有 `n` 种商品,每种商品的价值为 `v[i]`,成本为 `c[i]`,目标是在预算范围内最大化收益。此时可以通过如下状态转移方程实现: \[ dp[j] = \max(dp[j], dp[j - c[i]] + v[i]) \] 这里的 `dp[j]` 表示当剩余预算为 `j` 时的最大化收益[^1]。 #### 销售场景下的具体实例 考虑一个具体的例子:某商家提供多种商品供顾客选购,每种商品都有固定的价格和利润贡献值。如果允许客户多次购买同一种商品,则该问题可建模为完全背包问题。 ##### 输入描述 - 商品种类数 \( n \) - 预算总额 \( C \) - 每种商品的成本列表 \( costs[] \) - 每种商品的利润贡献列表 \( profits[] \) ##### 输出描述 返回能够获得的最大总利润。 ##### 示例代码 以下是一个基于上述模型的 C++ 实现代码: ```cpp #include <iostream> #include <vector> using namespace std; int completeKnapsack(int budget, vector<int> &costs, vector<int> &profits) { int n = costs.size(); vector<int> dp(budget + 1, 0); for (int i = 0; i < n; ++i) { // 遍历每一个商品 for (int j = costs[i]; j <= budget; ++j) { // 正序遍历容量 dp[j] = max(dp[j], dp[j - costs[i]] + profits[i]); } } return dp[budget]; } int main() { int n, budget; cin >> n >> budget; // 输入商品数量和预算总额 vector<int> costs(n), profits(n); for (int i = 0; i < n; ++i) cin >> costs[i]; // 输入每种商品的成本 for (int i = 0; i < n; ++i) cin >> profits[i]; // 输入每种商品的利润 cout << completeKnapsack(budget, costs, profits); // 输出最大利润 } ``` 此代码实现了完整的完全背包算法逻辑,并适用于销售场景中的优化决策问题[^3]。 #### 关键点解析 1. **正序遍历**:由于完全背包允许多次选择同一物品,因此内层循环需按从小到大顺序进行,以确保当前物品能重复利用。 2. **时间复杂度**:整个算法的时间复杂度为 \( O(N \times W) \),其中 \( N \) 是物品数目,\( W \) 是背包容量(即预算)[^4]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值