考试题目目录

1.木棍(暴搜 + 剪枝)

2.喷泉(树状数组)

一.木棍

时间限制:2000ms 空间限制:256MB
输入文件:stick.in 输出文件:stick.out
题目描述
乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位。
然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度。
请你设计一个程序,帮助乔治计算木棒的可能最小长度。
每一节木棍的长度都用大于零的整数表示。
输入格式
输入包含多组数据,每组数据包括两行。
第一行是一个不超过64的整数,表示砍断之后共有多少节木棍。
第二行是截断以后,所得到的各节木棍的长度。
在最后一组数据之后,是一个零。
输出格式
为每组数据,分别输出原始木棒的可能最小长度,每组数据占一行。

样例

样例输入

复制9
5 2 1 5 2 1 5 2 1

样例输出

复制6
数据范围与提示

1 <= N <= 60

题目分析:这是一道非常非常经典的搜索题,搜起来没难度,就是剪枝要100分,少一步,就暴零......

(1)首先对所有的小木棍进行排序,从大到小。

(2)算出所有小木棍长度的和Sum,再取小木棍中最长的一根M,i从M到Sum枚举我们最后合并的长度,在满足Sum%i == 0的前提下,对i进行搜索判定,如果可以,输出i,结束循环,否则继续下去。(答案最大为Sum)

(3)如果在搜索第j根小木棍时发现小木棍不能拼好,那么后面所有和j相同长度的小木棍就不搜了。

(4)已经使用过的木棍,不再使用。

#include <cstdio>
#include <algorithm>
using namespace std ;
const int MAXN = 65 ;
int n, a[MAXN], Sum = 0 ;
bool Vis[MAXN] ;
bool dfs(int Num, int tot, int goal, int cnt)
{if(Num == goal && tot == n)    return true ;if(Num == goal)  Num = 0, cnt = 1 ;for(int i = cnt; i <= n; i ++){if(Num + a[i] > goal) continue ;if(Vis[i] == 1) continue ;Vis[i] = 1 ;if(dfs(Num + a[i], tot + 1, goal, i + 1) == true){return true ;}Vis[i] = 0 ;if(Num + a[i] == goal)  return false ;//很明显这根木棍能凑出来,说明后面有木棍凑不出来,即这个数不满足 if(Num == 0)    return false ;//一直没有找到合适的木棍 while(a[i] == a[i + 1] && i < n) i ++ ;}return false ;
}
bool cmp(int a, int b)
{return a > b ;
}
int main()
{//freopen("stick.in", "r", stdin) ;//freopen("stick.out", "w", stdout) ;while(scanf("%d", &n) != EOF){if(n == 0)  return 0 ;Sum = 0 ;for(int i = 1; i <= n; i ++){scanf("%d", &a[i]) ;Sum += a[i] ;}sort(a + 1, a + n + 1, cmp) ; for(int i = a[1]; i <= Sum; i ++){if(Sum % i == 0){for(int j = 1; j <= n; j ++)  Vis[j] = 0 ;if(dfs(0, 0, i, 1) == true){printf("%d\n", i) ;break ;}}}}
}

二.喷泉

样例

样例输入1

复制3 7 6
10 8 C
4 3 C
5 6 D

样例输出1

复制9

样例输入2

复制2 4 5
2 5 C
2 1 D

样例输出2

复制0

样例输入3

复制3 10 10
5 5 C
5 5 C
10 11 D

样例输出3

复制10

题目分析:初看以为是dp中的01背包,但是看看数据范围,明显会超时,只得了50分(数据还是很良心的)。听老师讲解后发现这道题的正解是树状数组......

首先我们可以想方法用nlogn做出这道题,因为只需要选择两个物品,所以,我们用n枚举其中一个物品,用logn来枚举另外一个物品,这里用树状数组来查询还剩下m这么多钱可以得到的最大值。

(1)用钻石买一个,用金子买一个,则最大值为金子中可以买的最大值+钻石中可以买的最大值。

(2)用金子买两个:第一个用n枚举,每次用树状数组寻找前面C - s[i]还剩下的可以买的最大的一个美丽度喷泉。比较max,然后再将i的美丽度w与剩下s[i]到D这么多钱可以买的美丽度一次比较取最大值。**因为不能重复买一件物品,所以我们不能提前将所有的物品加入树状数组,只能从前往后加,但这样也不遗漏,因为最大的两件物品,一定一前一后,保证可以查询到,且不重。

(3)用钻石买两个同上,相当于要开两个树状数组,或者将前一个清零,两类物品的价值要分开存储。

(4)注意,我们可以提前将不可能买的起的物品淘汰掉。

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std ;
const int MAXN = 1e5 + 5 ;
int BIT[MAXN], n, C, D, ans = 0, ans1 = -1, ans2 = -1 ;
int a, b, cntc = 0, cntd = 0 ;
char l ;
struct Node
{int w, s ;
}cc[MAXN], dd[MAXN] ;
int LowBit(int x)
{return x - ((x - 1) & x) ;
}
void UpDate(int x, int y, int val)
{for(int i = x; i < y; i += LowBit(i)) BIT[i] = max(BIT[i], val) ;
}
int Qmax(int x)
{int ans = 0 ;for(int i = x; i >= 1; i -= LowBit(i)) ans = max(ans, BIT[i]) ;return ans ;
}
int main()
{scanf("%d%d%d", &n, &C, &D) ;for(int i = 1; i <= n; i ++){scanf("%d%d %c", &a, &b, &l) ;if(l == 'C'){if(b <= C){cc[++cntc].w = a ;cc[cntc].s = b ;ans1 = max(ans1, a) ;}}if(l == 'D'){if(b <= D){dd[++cntd].w = a ;dd[cntd].s = b ;ans2 = max(ans2, a) ;} }}if(ans1 != -1 && ans2 != -1)    ans = ans1 + ans2 ;for(int i = 1; i <= cntc; i ++){int Num = Qmax(C - cc[i].s) ;if(Num > 0)        ans = max(ans, cc[i].w + Num) ;UpDate(cc[i].s, C, cc[i].w) ;}for(int i = 1; i <= C; i ++)  BIT[i] = 0 ;for(int i = 1; i <= cntd; i ++){int Num = Qmax(D - dd[i].s) ;if(Num > 0)     ans = max(ans, Num + dd[i].w) ;UpDate(dd[i].s, D, dd[i].w) ;}printf("%d", ans) ;
} 

暑期集训第12次考试总结相关推荐

  1. 暑期集训1期11暑期集训一期12阶段性测验

    暑期集训1期11 1.树状数组模板 2.线段树模板 暑期集训一期12阶段性测验 T1棒棒糖之王(^)前面讲过 T2烤乐滋埋雷(模拟) 用一个数组存储每一列是不是有炸弹,再用一个数组表示每一行有没有,最 ...

  2. 8.8 正睿暑期集训营 Day5

    目录 2018.8.8 正睿暑期集训营 Day5 总结 A 友谊巨轮(线段树 动态开点) B 璀璨光滑 C 构解巨树 考试代码 A B C 2018.8.8 正睿暑期集训营 Day5 时间:3.5h( ...

  3. 7.30 正睿暑期集训营 A班训练赛

    目录 2018.7.30 正睿暑期集训营 A班训练赛 T1 A.蔡老板分果子(Hash) T2 B.蔡老板送外卖(并查集 最小生成树) T3 C.蔡老板学数学(DP NTT) 考试代码 T2 T3 2 ...

  4. 暑期集训3:几何基础 练习题D:  HDU - 2036 ​​​​​​​

    2018学校暑期集训第三天--几何基础 练习题D  --    HDU - 2036 改革春风吹满地 " 改革春风吹满地,  不会AC没关系;  实在不行回老家,  还有一亩三分地.  谢谢 ...

  5. 暑期集训1:C++STL 例2:UVA-10935

    2018学校暑期集训第一天--C++与STL 例二  --  UVA - 10935 Throwing cards away I Given is an ordered deck of n cards ...

  6. acm暑期集训_2020.07.02

    acm暑期集训_2020.07.02 任务清单 1. 回顾ZUCC蓝桥杯热身赛-1中A.B.C题中涉及的知识点 2. 补题-----ZUCC蓝桥杯热身赛-1中D题 A题------洛谷-P1548 棋 ...

  7. 8.10 正睿暑期集训营 Day7

    目录 2018.8.10 正睿暑期集训营 Day7 总结 A 花园(思路) B 归来(Tarjan 拓扑) C 机场(凸函数 点分治) 考试代码 A B C 2018.8.10 正睿暑期集训营 Day ...

  8. 题解报告(CDUT暑期集训——第一场)

    题解报告(CDUT暑期集训--第一场) A - Maximum Multiple HDU - 6298 思路:先按照题意打表 发现规律 就出来了(最开始没开long long贡献了3发 然后又忘了换行 ...

  9. 8.6 正睿暑期集训营 Day3

    目录 2018.8.6 正睿暑期集训营 Day3 A 亵渎(DP) B 绕口令(KMP) C 最远点(LCT) 考试代码 A B C 2018.8.6 正睿暑期集训营 Day3 时间:5h(实际) 期 ...

最新文章

  1. 用 Python 制作可视化报表,这也太快了!
  2. DNN结构:CNN、LSTM/RNN中的Attention结构
  3. 875. Koko Eating Bananas
  4. jieba分词并做分析
  5. Mysql报错:2006 - MySQL server has gone away
  6. SQL注入:4、数据库可写
  7. HDOJ 1698 Just a Hook(线段树成段更新)
  8. Struts2 文件上传 文件类型 大小过滤
  9. 安卓手机模拟路由器 测试WIFI信道遍历
  10. linux打补丁教程,Linux下patch打补丁命令
  11. 根轨迹 matlab 怎么画一半儿,现有 1020 个西瓜,第一天卖一半多两个,以后每天都卖剩下的一半多两个,编程计算几天后能把所有西瓜都卖完? 请编程实现_学小易找答案...
  12. 称重传感器(体脂体重模块)应用及特点
  13. mybatis 练习二(vue)
  14. 【++运算符重载】c++实现递增运算符重载
  15. python练习39:有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中。
  16. [Python] Python 绘制美队盾牌(含五星两种画法)
  17. Android判断是否为模拟器(实测夜神通过)
  18. 如何通过安装包安装应用到手机
  19. 什么是数据库连接池?
  20. 摄影测量航带设计程序

热门文章

  1. 【读书笔记】《深度专注力:管理精力和时间的9种方法》
  2. 电子技术——CMOS反相器
  3. (常用代码)原声JS 实现倒计时的效果。分/秒/毫秒/
  4. 暨南大学2019计算机分数线,2019暨南大学研究生分数线汇总(含2016-2019历年复试)...
  5. CodeForces 351B Jeff and Furik 概率DP 逆序对
  6. matlab升压斩波仿真,升压斩波电路设计与仿真.doc
  7. udig-1.4.0 开发环境搭建
  8. input file美化
  9. c语言能实现图片转字符画吗,图片转字符画
  10. Android HFP流程记录