1. 问题分析与动态规划思路拆解
这道题目描述了一个有趣的现实场景:Bessie需要捕捉N组蛇,每组蛇的数量不同。她可以改变捕网的大小,但每次改变都会产生空间浪费。我们的目标是找到在允许改变K次捕网大小的情况下,最小的总浪费空间。
1.1 问题重述与理解
首先,让我们更清晰地理解题目要求:
- 有N组蛇,每组蛇的数量为a_i
- 捕网初始大小可以任意设定
- 在捕捉过程中可以改变K次捕网大小
- 每次捕捉一组蛇时,如果捕网大小为s,蛇组大小为g,则浪费空间为s-g
- 需要计算所有组捕捉完成后的总浪费空间最小值
1.2 动态规划思路的形成
这个问题具有典型的动态规划特征:
- 最优子结构:最终的最优解可以由子问题的最优解组合而成
- 重叠子问题:在计算过程中会重复计算相同的子问题
- 状态转移:当前状态可以由之前的状态转移而来
我们定义状态f[i][j]表示捕捉前i组蛇,改变j次捕网大小时的最小总浪费空间。这里的"改变j次"包括初始设定捕网大小的那一次。
1.3 状态转移方程推导
状态转移的核心思想是:对于第i组蛇,考虑它和前面连续的几组蛇使用同一个捕网大小的情况。具体来说:
- 对于f[i][j],我们枚举k,表示从第k+1组到第i组使用同一个捕网大小
- 这个捕网的大小应该取这些组中最大的a值(因为捕网必须能装下最大的那组)
- 浪费空间就是:(最大a值)*(组数) - 这些组的总蛇数
- 然后加上f[k][j-1]的值,即前k组改变j-1次的最小浪费
因此,状态转移方程为:
f[i][j] = min(f[k][j-1] + max{a[k+1..i]}*(i-k) - sum{a[k+1..i]})
其中k从i-1递减到0
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 代码实现与核心细节解析
2.1 预处理与初始化
cpp复制#include <bits/stdc++.h>
#define MAX 405
using namespace std;
int n, m;
int a[MAX], f[MAX][MAX], s[MAX];
- 使用
bits/stdc++.h包含所有标准库头文件 - 定义最大组数MAX为405(略大于题目上限400)
- 声明变量:
- n:
