Hello大家好我是小亦今天又是来写了来自NOIP的2001普及组题目,难度为普及-,其实这道题呢挺简单的但是看着正确率却不高啊qwq,话不多说今天呢我来跟大家来一一分析这道题的思路与代码都会提供哈~
其实在我看来是一个非常经典的动态规划问题,通常称为“装箱问题”或“背包问题的变种”。目标是将一组物品放入一个容量有限的箱子中,使得箱子的剩余空间最小,所以很适合大家学动态规划DP或背包拿来试试手下面说分析:
思路分析:
理解问题:我们需要找到一种方法来放置物品,使得箱子的剩余空间最小。
动态规划:使用动态规划(DP)来解决这个问题。我们可以定义一个DP数组,其中 dp[i] 表示容量为 i 的箱子的最大填充量。
状态转移:对于每个物品,我们有两种选择:不放入当前物品或放入当前物品。我们需要找到这两种选择中能够使得箱子剩余空间最小的一种。
初始化:初始化DP数组,dp[0] = 0,表示容量为0的箱子剩余空间为0。
遍历物品:遍历每个物品,对于每个物品,更新DP数组。
计算结果:最终,箱子的最小剩余空间为 V - dp[V],其中 V 是箱子的总容量。
实现步骤:
读取输入:读取箱子容量 V 和物品总数 n。
读取物品体积:读取每个物品的体积。
初始化DP数组:创建一个大小为 V+1 的数组,用于 ` 存储每个容量下的最大填充量。
动态规划:使用动态规划更新DP数组。
计算最小剩余空间:计算 V - dp[V] 作为结果。
我这么说大家应该能看懂吧不懂都可提问我会在线回(但是有时候忙没时间看哦qwq),说完了思路我们就来看代码吧、
#include <iostream>
#include <vector>
using namespace std;
int main() {
int V, n;
cin >> V >> n;
vector<int> weights(n);
for (int i = 0; i < n; ++i) {
cin >> weights[i];
}
vector<int> dp(V+1, 0);
for (int i = 0; i < n; ++i) {
for (int j = V; j >= weights[i]; --j) {
dp[j] = max(dp[j], dp[j - weights[i]] + weights[i]);
}
}
int minSpace = V - dp[V];
cout << minSpace << endl;
return 0;
}
这次的代码没写思路希望大家不要介意(轻点喷可以吗qwq)
![feicha.png](https://cdn.acwing.com/media/article/image/2024/10/09/473323_5616ba3386-feicha.png)