问题描述
小张最近沉迷上一款手机游戏北理工的恶龙。在这个游戏中你通过提升攻击力击败恶龙,打败所有恶龙后你可以获得游戏的胜利。
在这款游戏中,每一条恶龙有一个难度值
x
i
x_i
xi和一个经验值
y
i
y_i
yi。游戏中的英雄具有攻击力 A 。游戏一开始英雄的攻击力 A=0 。打到一条恶龙你的攻击力需要大于难度值
x
i
x_i
xi 。在你击败恶龙以后,你的攻击力会增加经验值
y
i
y_i
yi。
当然,你有时需要额外提升你的攻击力,此时你只需氪金1元,就能增长一点攻击力。小张想知道,如果他自己决定挑战恶龙的顺序,要想击败所有恶龙至少需要氪金多少钱?
输入
第一行一个数 n(
1
≤
n
≤
200000
1 \leq n \leq 200000
1≤n≤200000) 。
接下来 n 行每行两个数
x
i
,
y
i
x_i,y_i
xi,yi(
0
≤
x
i
≤
1000000
,
−
1000000
≤
y
i
≤
1000000
0 \leq x_i \leq 1000000, -1000000 \leq y_i \leq 1000000
0≤xi≤1000000,−1000000≤yi≤1000000) 。
输出
一个整数,表示小张最少需要氪金多少钱。
注
直接打败第一条恶龙,此时 A=1 ,花费0元。
直接打败第二条恶龙,此时 A=2 ,花费0元。
氪金3元,此时 A=5 ,打败第三条恶龙,此时 A=3 。
最后直接打败第四条恶龙。
其实我觉得写任何算法题之前,都需要先分析分析,比如这个题,很明显就得把龙先分个类对吧,剩下的就看注释吧
用例
输入(1)
4
0 1
1 1
5 -2
2 -1
输出(1)
3
代码
#include <stdio.h>
#include <stdlib.h>//这是第十五题 北理工的恶龙
typedef struct{
long long int x;
long long int y;
long long int z;
} devil_dragon; //首先我们定义一个结构体来存储恶龙的全部信息
devil_dragon exp_given[200001]={},exp_taken[200001]={};
int comp(const void* a,const void* b){
return (*(devil_dragon*)a).x-(*(devil_dragon*)b).x;
}
int comp2(const void* a,const void* b){
return (*(devil_dragon*)b).z-(*(devil_dragon*)a).z;
}
int main()
{
long int n;
long long int c1,c2;
long long int p=0,q=0,A=0;
long long int money=0;
scanf("%ld",&n);
for(long int i=1;i<=n;i++)
{
scanf("%lld",&c1);
scanf("%lld",&c2);
if(c2>=0)
{
exp_given[p].x=c1;
exp_given[p].y=c2;
p++;
}
else
{
exp_taken[q].x=c1;
exp_taken[q].y=c2;
exp_taken[q].z=c1+c2;
q++;
}
} //我们将所有的恶龙按照给经验和减经验分为两组
qsort (exp_given,p,sizeof(devil_dragon),&comp);
qsort (exp_taken,q,sizeof(devil_dragon),&comp2);
for(long int i=0;i<p;i++)
{
if(A>=exp_given[i].x)
{
A=A+exp_given[i].y;
}
else
{
money=money+exp_given[i].x-A;
A=exp_given[i].x;
A=A+exp_given[i].y;
}
} //我们先杀给经验的恶龙,按需要的攻击力升序来杀
for(long int i=0;i<q;i++)
{
if(A>=exp_taken[i].x)
{
A=A+exp_taken[i].y;
}
else
{
money=money+exp_taken[i].x-A;
A=exp_taken[i].x;
A=A+exp_taken[i].y;
}
} //我们再杀减经验的恶龙,因为我们每杀完一只恶龙,我们的等级一定大于等于这只恶龙的x+y,所有我们按x+y的降序排序来杀,这里应用贪心算法,每次都使得自己剩下的攻击力最大
printf("%lld\n",money);
return 0;
}