acwing_4700_何以包邮
水一期
题目描述
新学期伊始,适逢顿顿书城有购书满 元包邮的活动,小 同学欣然前往准备买些参考书。
一番浏览后,小 初步筛选出 本书加入购物车中,其中第 本()的价格为 元。
考虑到预算有限,在最终付款前小 决定再从购物车中删去几本书(也可以不删),使得剩余图书的价格总和 在满足包邮条件()的前提下最小。
试帮助小 计算,最终选购哪些书可以在凑够 元包邮的前提下花费最小?
输入格式
输入的第一行包含空格分隔的两个正整数 和 ,分别表示购物车中图书数量和包邮条件。
接下来输入 行,其中第 行()仅包含一个正整数 ,表示购物车中第 本书的价格。
输入数据保证 本书的价格总和不小于 。
输出格式
仅输出一个正整数,表示在满足包邮条件下的最小花费。
数据范围
的测试数据满足:;
全部的测试数据满足:,每本书的价格 且 。
输入样例1:
输出样例1:
样例1解释
购买前两本书 即可包邮且花费最小。
输入样例2:
输出样例2:
样例2解释
仅购买第三本书恰好可以满足包邮条件。
输入样例3:
输出样例3:
样例3解释
必须全部购买才能包邮。
dfs法
算是复习一下,优化一下能拿70
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| #include<iostream> #include<cstring> using namespace std;
const int N = 50; #define inf 0x3f3f3f3f
int n, m; int a[N], minn = inf; bool flag[N];
void dfs(int now) { if(now >= m) { minn = min(minn, now); return; } for(int i = 1; i <= n; i ++) { if(flag[i] == false) { flag[i] = true; dfs(now + a[i]); flag[i] = false; } } }
int main() { memset(flag, false, sizeof(flag)); cin >> n >> m; for(int i = 1; i <= n; i ++) cin >> a[i]; dfs(0); cout << minn << endl; return 0; }
|
状压法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| #include<iostream> #include<cstring> using namespace std;
const int N = 50; const int inf = 1e8;
int n, m; int a[N], minn = inf;
int main() { cin >> n >> m; for(int i = 0; i < n; i ++) cin >> a[i];
for(int i = 0; i <= 1 << n; i ++) { int sum = 0; for(int j = 0; j < n; j ++) { if(i >> j & 1) { sum += a[j]; } } if(sum >= m) { minn = min(minn, sum); }
}
cout << minn << endl; return 0; }
|
动规法
类似于01背包,但要求选取的所有物品价值总和越小越好。01背包要求不大于某个数。
则可以转化为选取总和小于sum - x,越大越好。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| #include<iostream> #include<cstring> using namespace std;
const int N = 50; const int M = 3000010; const int inf = 1e8;
int n, m, sum, re; int a[N], minn = inf; int v[M];
int main() { cin >> n >> m; for(int i = 1; i <= n; i ++) cin >> a[i], sum += a[i]; re = sum - m; for(int i = 1; i <= n; i ++) { for(int j = re; j >= a[i]; j --) { v[j] = max(v[j - a[i]] + a[i], v[j]); } } cout << sum - v[re] << endl; return 0; }
|