引爆炸弹

贪心

【问题描述】

有 n 个炸弹,有些炸弹牵了一根单向引线(也就是说引线只有在这一端能被炸弹点燃),只要引爆了这个炸弹,用引线连接的下一个炸弹也会爆炸。每个炸弹还有个得分,当这个炸弹被引爆后就能得到相应得分。现在要你引爆 k 个炸弹,使得得分最大。

【输入】

第一行两个整数 n、k。

接下来的 n 行,每行两个整数 a[i]、b[i]。a[i]表示这个炸弹用引线连接的下一个炸弹,如果a[i]为 0,则表示这个炸弹没有连接引线。b[i]表示这个炸弹的得分。

【输出】

最大得分。

【数据规模】

1≤b[i]≤1000000

对于 30%的数据,n≤1000,k≤30;

对于 60%的数据,n≤50000,k≤100;

对于 100%的数据,n≤200000,k≤500。

【解题过程】

题目给出的是一棵树(注意其实有可能是环,题目并没有明说,但是理论上来讲最好要先用 Tarjan 缩点然后编程复杂度就呵呵,而其实题目的所有数据中并没有出现环),很明显应该引爆叶节点。所以我们就计算出引爆每个叶节点能得到的最大分数。但是两个叶节点往后的路径可能会重叠,这时应该将后面的那些节点分配给能够得到较大分数的那个叶节点。怎么知道哪个叶节点更「划算」?我们可以先遍历一遍图,维护每个节点的一个 v 值,v(i) = max{ v(j)+b(i), <j, i>∈E },并用 from(i) 记录下从哪个点转移过来是最大值。然后再遍历一遍图,对于一个结点 i,用 f(i) 表示从它开始引爆能够得到的最大得分,如果它相连的结点 j 的 from 不是 i,那么 f(i) = b(i),否则 f(i) 等于 b(i)+f(j)。最后根据 f 值排序取前 k 个。

注意图的遍历最好用 BFS,DFS 可能会爆栈(但是貌似实际上不会?)。

第一次提交 AC。

 

取石子

贪心

【问题描述】

有 n 个石子围成一圈,每个石子都有一个权值 a[i]。给你一次且仅一次取石子的机会,取石子的块数不限,取完后统计得分。现在要使取出的石子得分最大。

每个石子的得分计算公式是 a[i]*d,d 表示这个石子到两边被取了的石子的距离和。如{1,2,7,9,8,6,4,5,3,10}这些权值的石子围成一圈,不同取法有不同得分:

【输入】

第一行一个整数 n。

接下来 n 行,每行一个整数 a[i]。

【输出】

仅一个整数,表示最大得分。

【输入样例】

5

1

2

3

4

20

【输出样例】

80

【数据规模】

1≤a[i]≤100000

对于 30%的数据,n≤60;

对于 60%的数据,n≤300;

对于 100%的数据,n≤100000。

【解题过程】

其实一开始有直觉感觉好像取两个的时候就是最大的,但是想想不太靠谱就往RMQ+贪心去想了。大致就是每次在分隔出的几个区间中找权值最大的点判断取了这个点之后解是否更优,如果是就取,然后继续贪心;否则当前就是最大值。

然后 WJZ 大神说取两个一定比取两个以上更优,而且给出了证明(orz)。其实再想想发现肯定是对的。取两个数字当然是取最大的那两个数字,那么在区间中如果再取一个数字,这个数字不会大于已经取了的两个数字,但是计算距离的时候由于多了一个障碍点距离也就少了1,变得更差了。

但是注意取两个不一定比取一个更优,所以要看这两种情况哪种更优。

注意要 long long。以及找最大的两个值的时候写错了。

我是这样写的

if a[i] > max

max2 = max

max = a[i]

还能逗逼更多么?

 

化工厂装箱员

动态规划

【输入样例】

11

A

B

C

A

B

C

A

B

C

A

B

【输出样例】

3

【解题过程】

首先看题目花了很久。

然后果断搜索了。看前两题贪心以为今天贪心专场,然后没有想到这道题的正确贪心方法,后来才知道不是贪心。

有一个显而易见的但是错的贪心方法:将目前手中数目最多的那种物品先装箱。能过 7 个点。

正解是动规:

用 f(i, A, B, C) 表示已经前 i-1 个物品已经取出,而当前的 10 个物品中,A 类物品有 A 个,以此类推。则

f(i, A, B, C) = max{ f(i+A, A', B, C), f(i+B, A, B', C), f(i+C, A, B, C') }

其中 f(i+A, A', B, C) 表示将 10 个物品中的 A 物品全部装箱了,而 A' 表示接下来从流水线取出的 A 个物品中有多少个 A 类物品,其他两个表达式是类似的意思。

第一次提交 20 分。搜索都能写错我也是醉了。后来先做了一次贪心作为初始较优解来剪枝还是只能过 7 个点。动规大法好。

08day2的更多相关文章

  1. 二模08day2解题报告

    T1.引爆炸弹(bomb) N个炸弹构成一棵树,引爆一颗叶节点,会一直引爆到根节点.每颗炸弹有一个价值,求引爆k个炸弹的最大价值. 既然是一棵树,那么自然想到dp.所以先树形dp了一遍(由于可能出现多 ...

随机推荐

  1. SGU 105

    There is sequence 1, 12, 123, 1234, ..., 12345678910, ... . Given first N elements of that sequence. ...

  2. java基础知识回顾之接口

    /* abstract class AbsDemo { abstract void show1(); abstract void show2(); } 当一个抽象类中的方法都是抽象的时候,这时可以将该 ...

  3. JDBC第一次学习

     JDBC(Java Data Base Connectivity,java数据库连接),由一些类和接口构成的API,它是J2SE的一部分,由java.sql,javax.sql包组成. 应用程序.J ...

  4. unity HideInInspector 默认值 坑 记录 bug

    1:   如果  一个public字段 刚开始有默认值,然后你你觉得这个值不应该给别人看设置为HideInInspector 后,你再在代码里面调整这个默认属性的值,这个时候代码里面调整的值无效.   ...

  5. Model的验证

    ModelValidator与ModelValidatorProvider ModelValidator public abstract class ModelValidator { public v ...

  6. MDX语法

    https://msdn.microsoft.com/zh-cn/library/ms145506.aspx

  7. 蒙特罗卡π算法(C++语言描述)

    圆的面积计算公式为:S=π*r*r 将圆放到一个直角坐标系中,如图黄色部分的面积是S/4=(π*r*r)/4;如果我们将取一个单位圆,则S/4=π/4. 因为是单位圆,半径为1,所以图中红色正方形的面 ...

  8. Java 全角字符转半角字符

    1.java代码里有时候会遇到代码注入的安全问题,为了防止这种问题,增加了一个过滤功能.主要是过滤全角字符,把url不能识别的全角字符转换成半角字符 public class Test { publi ...

  9. java验证码-汉字验证码

    今天整理了一个java实现的汉字输入验证码 主要包含两个类,一个是生成验证码,一个是判断验证码输入是否正确 实现原理非常简单,将汉字和干扰线生成图片并将汉字保存到session,前台获取每次生成验证码 ...

  10. python类的简单介绍

    类是面向对象编程的核心, 它扮演相关数据及逻辑的容器角色.它们提供了创建“真实”对象(也就是实例)的蓝图.因为Python 并不强求你以面向对象的方式编程(与Java 不同), 此刻你也可以不学习类. ...