专栏文章
题解:UVA10482 The Candyman Can
UVA10482题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miqippdp
- 此快照首次捕获于
- 2025/12/04 05:27 3 个月前
- 此快照最后确认于
- 2025/12/04 05:27 3 个月前
题意
将 个数的数列分为 组,使总和最大的一组与总和和最小的一组的差最小。
思路
本体算法:动态规划。
建一个二维数组,用 dp 枚举 组里数的和,知道两组的和,使用减法算出第三组和。
使用 表示第一组和为 ,第二组和为 ,能否构造出来。
最后枚举每种存在的状态,直接求即可。
注意
直接枚举一个数有可能被算 次,要将新的可行状态标记为 ,每执行完上面这一段代码后将其变为 即可。
代码
CPP#include <iostream>
#include <algorithm>
#include <cstring>
// 将 int 定义为 long long 以处理更大范围的整数
#define int long long
// 处理测试用例的函数
void solve() {
// 元素数量
int n;
std::cin >> n;
// 存储元素的数组
int a[n + 1];
int sum = 0;
for (int i = 1; i <= n; ++i) {
std::cin >> a[i];
sum += a[i];
}
// 动态规划数组,dp[j][k] 表示某种状态
bool dp[1010][1010] = {false};
dp[0][0] = true;
for (int i = 1; i <= n; ++i) {
for (int j = sum; j >= a[i]; --j) {
for (int k = 0; k <= sum; ++k) {
if (dp[j - a[i]][k] || dp[k][j - a[i]]) {
dp[j][k] = true;
}
}
}
}
int min_diff = 1e18;
for (int i = 0; i <= sum; ++i) {
for (int j = 0; j <= sum; ++j) {
if (dp[i][j]) {
int third = sum - i - j;
int max_val = std::max({i, j, third});
int min_val = std::min({i, j, third});
min_diff = std::min(min_diff, max_val - min_val);
}
}
}
std::cout << min_diff << "\n";
}
int main() {
// 测试用例数量
int T;
std::cin >> T;
for (int case_num = 1; case_num <= T; ++case_num) {
std::cout << "Case " << case_num << ": ";
solve();
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...