问题描述
何以包邮? 题目链接
解题思路1
整个问题就是01背包问题
将问题转换为01背包模型
书本的总价格>=x并且 最小
可以将问题理解为 选取几本书使得书本的总价格<= sum - x的情况下,使得书本的总价格最大
文章来源:https://www.uudwc.com/A/b10Pr/
代码实现1
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 35, M = 3e5 + 10;
int f[N][M];
int a[N];
int main()
{
int n, x;
cin >> n >> x;
int sum = 0;
for (int i = 1; i <= n; i ++)
{
cin >> a[i];
sum += a[i];
}
int res = 0;
for (int i = 1; i <= n; i ++)
{
for (int j = 0; j <= sum - x; j ++)
{
f[i][j] = f[i - 1][j];
if (j >= a[i]) f[i][j] = max(f[i][j], f[i - 1][j - a[i]] + a[i]);
res = max(res, f[i][j]);
}
}
cout << sum - res;
return 0;
}
解题思路2
整个问题也可以看作是01背包问题
从前i本书中选择要被减掉的书,使得总价格>= x的所有选法
求所有选法集合中的价格最小值即是答案
文章来源地址https://www.uudwc.com/A/b10Pr/
代码实现2
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 35, M = 3e5 + 10;
int f[N][M];
int a[N];
int main()
{
int n, x;
cin >> n >> x;
int sum = 0;
for (int i = 1; i <= n; i ++)
{
cin >> a[i];
sum += a[i];
}
for (int i = 1; i <= n; i ++) f[i][sum] = sum;
for (int j = x; j <= sum; j ++) f[0][j] = sum;
int res = 3000010;
for (int i = 1; i <= n; i ++)
{
for (int j = sum; j >= x; j --)
{
f[i][j] = f[i - 1][j];
if (j + a[i] <= sum) f[i][j] = min(f[i][j], f[i - 1][j + a[i]] - a[i]);
if (f[i][j] >= x) res = min(res, f[i][j]);
}
}
cout << res;
return 0;
}