[日常训练] 买汽水
来源:互联网 发布:苹果root软件 编辑:程序博客网 时间:2024/05/17 01:11
【问题描述】
czyz暑期集训一共N天。由于jmy和lkf玩游戏总是输,作为惩罚,他需要给oiers买汽水。
jmy最多只能给大家花M元钱。由于每天汽水的价格都不固定,现在给出每天买汽水的花销,我们可以随意选择让jmy哪些天买汽水(当然总花费不能超过M)。请问最多一共能够花掉jmy多少钱呢?
暑假最多不超过40天,jmy给大家花的钱最多有一亿。
【输入格式】
输入第一行有两个整数N,M。 1<=N<=40,0<=M<=100000000。
接下来一行有N个数,第i个数表示第i天的汽水花销。每天汽水的花销p<=100000000。
【输出格式】
输出一行一个整数,表示我们最多能够花掉jmy多少钱。
【输入输出样例一】
drink.in
3 10
1 2 3
drink.out
6
【输入输出样例二】
drink.in
4 10
4 3 5 11
drink.out
9
【数据规模】
对于10%的数据,N<=10。
对于30%的数据,N<=20。
对于60%的数据,N<=30。
对于100%的数据,N<=40。
【10分】 01背包
【60分】 深搜 + 剪枝
直接暴力深搜,考虑如何剪枝:
[1]、将花销数组从大到小排序,这样在搜索时会优先选取花销大的搜索,加快效率。
[2]、记录上一次选取的位置
[3]、记录花销数组的后缀和,若此时将未搜索到的所有位置的花销全部计入总花销若未超出容量
[4]、记录最小的单天花销
【代码】
#include <iostream>#include <algorithm>#include <cstdio> using namespace std;const int N = 45;int a[N], c[N], n, m, Ans, mx = 0x3f3f3f3f; bool vis[N];void Dfs(const int &k, const int &lst, const int &w){ int tmp = w + c[lst + 1]; if (tmp <= Ans || w > m) return; if (tmp <= m && tmp >= Ans) return (void)(Ans = tmp); if (w > Ans) Ans = w; if (k > n || m - w < mx) return ; for (int i = lst + 1; i <= n; ++i) Dfs(k + 1, i, w + a[i]);}inline bool cmp(const int &x, const int &y){ return x > y; }int main(){ freopen("drink.in", "r", stdin); freopen("drink.out", "w", stdout); scanf("%d%d", &n, &m); for (int i = 1; i <= n; ++i) scanf("%d", &a[i]); sort(a + 1, a + n + 1, cmp); for (int i = n; i >= 1; --i) { c[i] = c[i + 1] + a[i]; if (mx > c[i]) mx = c[i]; } Dfs(1, 0, 0); printf("%d\n", Ans); fclose(stdin); fclose(stdout); return 0;}
【100分】 折半搜索
最大数据
考虑怎样
【代码】
#include <iostream>#include <cstdio>#include <algorithm>using namespace std;const int N = 45, M = (1 << 20) + 5;int a[N], b[N], c[N], d[N];int Ans, n, x, m;inline void Dfs1(const int &k, const int &w){ if (w > m) return ; if (k > a[0]) return (void)(c[++c[0]] = w); for (int i = 0; i <= 1; ++i) Dfs1(k + 1, w + (i ? a[k] : 0));}inline void Dfs2(const int &k, const int &w){ if (w > m) return ; if (k > b[0]) return (void)(d[++d[0]] = w); for (int i = 0; i <= 1; ++i) Dfs2(k + 1, w + (i ? b[k] : 0));}inline void CkMax(int &x, const int &y) {if (x < y) x = y;}int main(){ freopen("drink.in", "r", stdin); freopen("drink.out", "w", stdout); scanf("%d%d", &n, &m); for (int i = 1; i <= n; ++i) { scanf("%d", &x); if (i & 1) a[++a[0]] = x; else b[++b[0]] = x; } Dfs1(1, 0); Dfs2(1, 0); int l = 0, r = d[0]; sort(c + 1, c + c[0] + 1); sort(d + 1, d + d[0] + 1); while ((++l) <= c[0] && r) { while (c[l] + d[r] > m) r--; if (r) CkMax(Ans, c[l] + d[r]); } printf("%d\n", Ans); fclose(stdin); fclose(stdout);}
- [日常训练] 买汽水
- 买汽水
- Java - 华为机试训练 - 汽水瓶
- 训练二-买饮料
- 面试,递归:买汽水,1块钱可以买1瓶汽水,2个空瓶可以换一瓶汽水,3个瓶盖可以换一瓶汽水,问:20块可以买到多少瓶汽水
- HEU日常训练10.02
- 日常训练小结
- 日常训练20161012 道路网
- 日常训练20161012 醉酒
- 日常训练20161014 跟踪
- 日常训练20161018 证据
- 日常训练20161018 subset
- 日常训练 平均数
- 日常训练 水箱
- 日常训练 棋盘游走
- 日常训练 20170531 数字
- 日常训练 20170531 探险
- 日常训练 20170531 矩阵
- 命令行指定的类打入单独的DEX
- Linux常用命令
- CCS-js学习笔记【webstore快捷操作】
- 【DOS网络命令】-at的用法
- 第一篇博客
- [日常训练] 买汽水
- selenium ide脚本介绍
- [NOIP2017模拟]table
- dojo.query() 方法常见的css选择符语法
- 与String相关的一些习题:求最大子串,子串出现次数,字符串反转等
- python--我的大花莽【turtle画】
- LayoutInflator#Inflate(...)
- 单例模式的线程安全问题
- js获取某周、某月、下月、某季度的开始日期、结束日期及判断日期第几周