有N个货币,将其放入M个背包,使价值最大的背包和价值最小的背包的差值最小。 输入 第一行两个整数N,M .下一行N个整数,表示货币的价值。 输出 一行一个整数,表示最小的差距 的代码
时间: 2023-03-31 20:03:19 浏览: 104
我可以回答这个问题。这是一个经典的背包问题,可以使用动态规划来解决。首先将货币按照价值从大到小排序,然后定义一个二维数组dp,其中dp[i][j]表示将前i个货币放入j个背包中,使价值最大的背包和价值最小的背包的差值最小的最小值。状态转移方程为:dp[i][j] = min(dp[i-1][j], max(dp[k][j-1], sum[i]-sum[k])),其中sum[i]表示前i个货币的总价值,k从j-1到i-1枚举,表示将前i个货币分成j个背包,其中第j个背包包含第k+1到第i个货币,其余背包包含前k个货币,取其中差值最小的方案。最终答案为dp[N][M]。以下是代码实现:
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 1005;
const int MAXM = 105;
const int INF = x3f3f3f3f;
int N, M, val[MAXN], sum[MAXN], dp[MAXN][MAXM];
int main() {
cin >> N >> M;
for (int i = 1; i <= N; i++) {
cin >> val[i];
}
sort(val + 1, val + N + 1, greater<int>());
for (int i = 1; i <= N; i++) {
sum[i] = sum[i-1] + val[i];
}
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
dp[i][j] = INF;
if (i < j) continue;
if (j == 1) {
dp[i][j] = sum[i] - sum[];
} else {
for (int k = j-1; k < i; k++) {
dp[i][j] = min(dp[i][j], max(dp[k][j-1], sum[i]-sum[k]));
}
}
}
}
cout << dp[N][M] << endl;
return ;
}
阅读全文