点此看题面

大致题意: 有\(n\)张卡牌,每张卡牌有两种用法:使场上增加一个伤害为\(a_i\)的生物,或使场上所有生物伤害增加\(b_i\)。求最大总伤害。

三分

我们可以三分使用\(a_i\)的卡牌张数

证明如下:

假设使用\(a_i\)的卡牌张数最优为\(x\),此时选用的\(b_i\)总和为\(t\)。

  • 证明:从最优决策点向左总伤害值递减

    此时如果将一张选\(a_i\)的卡牌改为选\(b_i\),则伤害变化值应为\(b_i*(x-1)-a_i-t\)。

    因为原先状态为最优状态,所以该操作肯定不能使答案更优,也就是说:\(b_i*(x-1)-a_i-t\le0\)。

    再考虑若当前使用\(a_i\)的卡牌张数是\(y(y<x)\),选用的\(b_i\)总和为\(t'\),则伤害变化值应为\(b_i*(y-1)-a_i-t'\)。

    由于\(y<x\)且\(b_i>0\),所以\(b_i*(y-1)<b_i*(x-1)\)。

    由于使用\(a_i\)的卡牌张数减少,所以使用\(b_i\)的卡牌张数增加,因此\(t'>t\)。

    而\(a_i\)是不变的,且\(b_i*(x-1)-a_i-t\le0\),所以\(b_i*(y-1)-a_i-t'\)必然小于\(0\)。

    也就是说伤害变化值为负数,肯定是不优的。

    可见从最优决策点向左总伤害值递减

  • 证明:从最优决策点向右总伤害值递减

    此时如果将一张选\(b_i\)的卡牌改为选\(a_i\),则伤害变化值应为\(a_i+t-b_i*(x-1)\)。

    因为原先状态为最优状态,所以该操作肯定不能使答案更优,也就是说:\(a_i+t-b_i*(x-1)\le0\)。

    再考虑若当前使用\(a_i\)的卡牌张数是\(y(y>x)\),选用的\(b_i\)总和为\(t'\),则伤害变化值应为\(a_i+t'-b_i*(y-1)\)。

    由于\(y>x\)且\(b_i>0\),所以\(b_i*(y-1)>b_i*(x-1)\)。

    由于使用\(a_i\)的卡牌张数增加,所以使用\(b_i\)的卡牌张数减少,因此\(t'<t\)。

    而\(a_i\)是不变的,且\(a_i+t-b_i*(x-1)\le0\),所以\(a_i+t'-b_i*(y-1)\)必然小于\(0\)。

    也就是说伤害变化值为负数,肯定是不优的。

    可见从最优决策点向右总伤害值递减

综上所述,这是一个单峰函数,具备可三分性。

贪心求出最大伤害

上面我们已经证明了这道题有可三分性,那对于确定的使用\(a_i\)的卡牌张数,我们该如何求出最大伤害呢?

这可以用贪心

假设确定使用\(a_i\)共\(x\)张,则我们先定义一个\(res\)统计答案,初始化它为\(\sum_{i=1}^na_i\)。

由于使用\(a_i\)的卡牌张数是确定的,则对于第\(i\)张牌,它使用\(b_i\)能造成的伤害为\(b_i*x\)。

然后,我们用它使用\(b_i\)能造成的伤害,减去它使用\(a_i\)能造成的伤害,就得到了\(b_i*x-a_i\)。

显然,我们可以将这进行排序,然后选择最大的\(n-x\)个与\(res\)相加,这样就能清除原先选择\(a_i\)对\(res\)造成的贡献,并加上选择\(b_i\)对\(res\)造成的贡献。

具体实现详见代码。

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define LL long long
#define Gmax(x,y) (x<(y)&&(x=(y)))
using namespace std;
int n,a[N+5],b[N+5];LL s[N+5];
class FastIO
{
private:
#define FS 100000
#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
#define tn (x<<3)+(x<<1)
#define D isdigit(c=tc())
char c,*A,*B,FI[FS];
public:
I FastIO() {A=B=FI;}
Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
}F;
I LL GetAns(CI x)//求出在使用a[i]的卡牌张数为x时的最优答案
{
RI i;Reg LL res=0;for(i=1;i<=n;++i) res+=a[i],s[i]=1LL*b[i]*x-a[i];//初始化答案
for(sort(s+1,s+n+1),i=n;i^x;--i) res+=s[i];return res;//排序+贪心,返回答案
}
I LL Solve(RI l,RI r)//三分
{
RI i,mid1,mid2;Reg LL res=0,t;
W(r-l>2) mid1=l+(r-l)/3,mid2=r-(r-l)/3,GetAns(mid1)>GetAns(mid2)?r=mid2:l=mid1;//三分
for(i=l;i<=r;++i) t=GetAns(i),Gmax(res,t);return res;//求答案
}
int main()
{
RI i;for(F.read(n),i=1;i<=n;++i) F.read(a[i],b[i]);//读入数据
return printf("%lld",Solve(1,n)),0;//输出答案
}

【CCPC-Wannafly Winter Camp Day4 (Div1) I】咆咆咆哮(三分+贪心)的更多相关文章

  1. 2020 CCPC Wannafly Winter Camp Day1 C. 染色图

    2020 CCPC Wannafly Winter Camp Day1 C. 染色图 定义一张无向图 G=⟨V,E⟩ 是 k 可染色的当且仅当存在函数 f:V↦{1,2,⋯,k} 满足对于 G 中的任 ...

  2. CCPC-Wannafly Winter Camp Day4 Div1 - 咆咆咆哮 - [三分+贪心]

    题目链接:https://zhixincode.com/contest/18/problem/I?problem_id=267 题目描述 输入描述 输出描述 一行一个整数表示答案. 样例输入 1 32 ...

  3. Wannafly Winter Camp Day8(Div1,onsite) E题 Souls-like Game 线段树 矩阵乘法

    目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog @ Problem:传送门  Portal  原题目描述在最下面.  简单的 ...

  4. CCPC-Wannafly Winter Camp Day4 Div1 - 置置置换 - [DP]

    题目链接:https://zhixincode.com/contest/18/problem/G?problem_id=265 题目描述 wls有一个整数 $n$,他想请你算一下有多少 $1...n$ ...

  5. CCPC-Wannafly Winter Camp Day4 Div1 - 最小边覆盖 - [线段树]

    题目链接:https://zhixincode.com/contest/18/problem/C?problem_id=261 样例输入 1 4 21 23 4 样例输出 1 Yes 样例输入 2 4 ...

  6. CCPC-Wannafly Winter Camp Day4 Div1 - 夺宝奇兵 - [简单思维题]

    题目链接:https://zhixincode.com/contest/18/problem/A?problem_id=259 题目描述 wls正在玩一个寻宝游戏. 宝藏一共有 $n$ 种,都藏在一个 ...

  7. 【CCPC-Wannafly Winter Camp Day4 (Div1) G】置置置换(动态规划)

    点此看题面 大致题意: 求出有多少个长度为\(n\)的排列满足对于奇数位\(a_{i-1}<a_i\),对于偶数位\(a_{i-1}>a_i\). 考虑打表? 考虑每次只有一个数\(n\) ...

  8. 【CCPC-Wannafly Winter Camp Day4 (Div1) A】夺宝奇兵(水题)

    点此看题面 大致题意: 有\(n\)种宝藏,每种各两个.让你依次获得\(1\sim n\)号宝藏,然后依次获得剩余的\(n\sim1\)号宝藏,求最少步数. 简单结论 其实这题有一个十分简单的结论,即 ...

  9. 【CCPC-Wannafly Winter Camp Day4 (Div1) C】最小边覆盖(简单题)

    点此看题面 大致题意: 给你一个边集的子集,问你这可不可能是这张图的最小边覆盖. 大致思路 考虑到,如果一条边连接的两个点度数都大于等于\(2\),则这条边完全可以删去. 因此,我们只要判断是否存在这 ...

随机推荐

  1. MongoDB安装为windows服务

    MongoDB 下载 下载地址:http://www.mongodb.org/downloads 下载安装完成之后 第一步 创建D:\Program Files\mongodb\data 目录第二步 ...

  2. spring session使用日志

    请求进入和退出时,filter触发session的提取和保存   getAttribute时会查询数据库 setAttribute会保存到数据库 daemond线程定时自动删除过期的session s ...

  3. XAMPP 更换其它路径

    打开安装路径: xampp\apache\conf\httpd.conf DocumentRoot “C:/xampp/htdocs” <Directory “C:/xampp/htdocs”& ...

  4. Serializable深入理解

    1.什么是序列化,解决什么问题 序列化可以对象的状态信息转换成可以持久化或者可以传输形式的过程.一般是转为字节数据.而把字节数组还原成原来同等对象的过程成为反序列化. 在Java中,对象的序列化与反序 ...

  5. set学习(系统的学习)

    set是STL中一种标准关联容器.它底层使用平衡的搜索树——红黑树实现,插入删除操作时仅仅需要指针操作节点即可完成,不涉及到内存移动和拷贝,所以效率比较高.set,顾名思义是“集合”的意思,在set中 ...

  6. [转]关于Jquery的DataTables里TableTools的应用

    本文转自:http://147068307.iteye.com/blog/1700516 最近在产品中使用了TableTools这个工具,主要用来实现导出和复制功能. 但是在实际的运用中出现了以下相关 ...

  7. HDU——Cover——————【技巧】

    Cover Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  8. B树和B+树对比,为什么MySQL数据库索引选择使用B+树?

    一 基础知识 二叉树 根节点,第一层的节点 叶子节点,没有子节点的节点. 非叶子节点,有子节点的节点,根节点也是非叶子节点. B树 B树的节点为关键字和相应的数据(索引等) B+树 B+树是B树的一个 ...

  9. JNI:在线程或信号处理函数中访问自定义类

    在写一个Tomcat应用,类需要被信号处理函数回调,可是在单独的程序中测试没用问题: void OnSingalHandler(int sig) { ... JNIEnv* env=NULL; if ...

  10. intellijidea课程 intellijidea神器使用技巧 6-1 Spring的关联

    待学完spring之后再来看 Spring的关联位置:菜单->File->Project Structure->Facets功能:帮助管理Spring容器.还提供了很多其他的管理,比 ...