挖矿 +
题目描述
有N名矿工在挖矿。工厂预先给第i名矿工支付了Mi元工资,他每挖一吨矿需要消费Ki元头 余下的钱不足Ki元,他就停止挖矿。他每挖一吨矿,工厂会立即奖励他2元钱。奖励的钱于挖矿的消费。
给出矿工的信息,请你计算一下矿工们总共可以挖出多少吨矿,以及哪个矿工挖的矿最多。
输入格式
第1行:1个整数N,表示矿工的人数(1 ≤ N ≤ 70)
接下来2N行,每2行描述1名矿工。第1行是一字符串(长度不超过20个字符),表示矿工的姓名,第2行 2个整数,分别表示Ki(12 ≤ Ki ≤ 400)和Mi(1 ≤ Mi ≤ 10000)
输出格式
第1行:1个整数,表示矿工们总共可以挖出多少吨矿
第2行:1个字符串,表示挖矿最多的矿工的姓名。如果多个矿工挖得一样多,输出最靠前的1个人。
样例输入
1 | 4 |
样例输出
1 | 14 |
数据范围与提示
COCI16-17 2# Go
分析
模拟求出每一个工人的最大挖矿数,累加并记录最大值即可
AC代码
1 |
|
最小乘积 ++
题目描述
给出0~9这10个数字的个数,放在数组A中。A[0]表示数字0的个数,A[1]表示数字1的个数,…,A[9]表示数字9的个数。
你要用这些数字构造整数A和B,A恰好有W1位,B恰好有W2,允许A和B出现前导0。要求数字i在A和 B中出现的次数之和不超过A[i]。
数据保证数组A的元素之和至少为W1+W2
在所有的合法整数对A、B中,找出它们乘积最小的一对数。
输入格式
第1行:10个整数,表示数组A, 0 ≤ A[i] ≤ 20
第2行:1个整数,表示W1 1 ≤ W1 ≤ 9
第3行:1个整数,表示W2 1 ≤ W2 ≤ 9
输出格式
第1行:1个整数,表示A和B的最小乘积
样例输入
1 | 0 1 1 2 1 1 0 0 0 0 |
样例输出
1 | 3042 |
分析
要让乘积尽量小,显然 $ a $ 和 $ b $ 都尽量小。利用贪心的思想,去构造数字 $ a $ 和 $ b $ 。
首先,题目设定允许有前导 $ 0 $ ,因此如果有数字 $ 0 $ ,则尽量安排给位数小的数(这一点在考试时没想到,丢了48分),因为如果能够让 $ a $ 或者 $ b $ 成为 $ 0 $ ,则乘积可以达到理论上的最小值: $ 0 $
如果数字 $ 0 $ 的个数不能让 $ a $ 或者 $ b $ 变为0,把0全部安排给位数小的数,也比两边分配更优。可以把分配了
所有的 $ 0 $ 后剩余的位数当作需要构造的位数。
分配了数字 $ 0 $ ,再从小到大考虑其他分配其它的数字。显然,需要的数字的个数是 $ W1+W2 $ .我们先从 $ A $ 数组中从 $ 1 $ 到 $ 9 $ 的顺序把数字逐个存放在另一个数组 $ B $ 中,再轮流从 $ B $ 数组中取出数字填在 $ a $ 和 $ b $ 的各个数
位上。
当位数小的数填完之后,再把剩余的数字全部填在位数大的数中。
AC代码
1 |
|
回文数组 **
题目描述
给定有N个整数的数组A,下标从1到N。如果对每一个下标i均满足A[i] =A[N-i+1],则称数组是回文的。
例如,数组A={1,2,3,2,1}就是回文数组。
如果数组A不是回文的,可以采用合并两个相邻元素的方法去得到回文数组。注意,每操作一次,数组的元素数量减少1。
例如,数组A={1,2,3}不是回文数组,但是通过合并A[1]和A[2],得到{3,3}就是回文数组了。
显然,无论给出怎样的数组元素,最多经过N-1次操作,合并为一个数时,数组A一定是回文数组了。
因此,本题一定有解。
然而问题来了:对于给定的数组A,最少经过多少次操作,能让A变成回文数组?
输入格式
第1行:1个整数N,表示数组A的元素个数
第2行:N个空格分开的整数,表示数组A
输出格式
第1行:1个整数,表示最少的操作次数
样例输入
1 | 4 |
样例输出
1 | 2 |
分析
左右横跳之术 很明显,在这道题中因为是累加,较大数是无法变成较小数的,所以肯定是考虑将较小数累加为较大数,而边缘的数肯定不可能与中间的数对称,所以每次只考虑边缘的两个数,不同就累加较小数,直到左右数字相同或左右两个指针相遇
AC代码
1 |
|
乌龟 ++++
题目描述
一只乌龟由于智商低下,它只会向左或向右走,不过它会遵循主人小h的指令:F(向前走一步),T(掉头)。
现在小h给出一串指令,由于小h有高超的计算能力,他可以马上知道乌龟最后走到哪里。为了难倒小h,他的好朋友小c就说,现在让你修改其中n个指令,使得乌龟移动到离起点最远的地方。(修改是指“T”变成“F”,或“F”变成“T”,可以对同一个指令多次修改)。乌龟一开始在0点
输入格式
第1行:一个字符串S代表指令
接下来一行一个整数n,表示要修改的指令个数
输出格式
第1行:一个整数,表示乌龟所能移动到的最远距离。
样例输入
1 | FFFTFFF |
样例输出
1 | 6 |
分析
这道题有两种解法,记忆化搜索和动态规划,这里讲解记忆化搜索
这道题用爆搜是很容易想到的,但超时就和想到一样容易(
记忆化是一个方法,这里用f[i][j][k][l]
表示执行到第i
条指令,已经修改了j
条指令,距离原点为k
(有正负两种情况),当前方向为l
(0向左,1向右)的最远距离,函数参数同理
讨论一下决策方案,最基本的分为当前位置为F
和为T
两种情况,且分别有改和不改两种
设当前状态为dfs(now,cnt,sum,fx)
- 当为
T
且要改时,则now
加一,cnt
加一,sum
根据fx
加一或减一,即dfs(now + 1, cnt + 1, sum + ((fx == 0) ? 1 : -1), fx)
- 当为
T
且不改时,则now
加一,cnt
和sum
不变,fx
变为相反值,即dfs(now + 1, cnt, sum, (fx == 0) ? 1 : 0)
- 当为
F
且要改时,则now
加一,cnt
加一,sum
不变,方向变为相反值,即dfs(now + 1, cnt + 1, sum, (fx == 0) ? 1 : 0)
- 当为
F
且不改时,则now
加一,cnt
加一,sum
根据fx
加一或减一,即dfs(now + 1, cnt, sum + ((fx == 0) ? 1 : -1), fx)
除以上四种情况以外,也可选择将当前命令改变两次,则cnt
加二其它不变,即dfs(now, cnt + 2, sum, fx)
如果now
超过s
的长加一或cnt
超过n
,都不符合,执行return
f
数组为记忆化数组,如果当前情况计算过了,也return
如果now
等于s
的长加一,且cnt
等于n
,则此种情况计算完毕,将sum
的绝对值与ans
比较保存答案并return
AC代码
1 |
|