猫咪蠕虫入侵
时间限制: 1 Sec 内存限制: 128 MB题目描述
猫咪蠕虫入侵是一种单人闯关小游戏,你需要操控一堆小小的蠕虫,你需要到达终点,在路上你可以通过吃猫咪来增加蠕虫的个数,但也有陷阱会使你的蠕虫死亡。
现在 dodo 对这款游戏进行了简化,在游戏的一开始,你有 n 只蠕虫,在途中一共有 m 的陷阱和 k 只猫咪,每个陷阱和猫咪有一个位置 di(位置两两不同)。你从第一个猫咪或陷阱出发直到最后一个猫咪或陷阱结束游戏。你可以选择一些猫咪并把她吃掉来得到 x 只蠕虫的收益,但每吃掉一只猫咪你需要消耗 ei 点的精力值。对于每一个陷阱,给出陷阱的长度 li,在陷阱前,你可以通过将蠕虫叠起来来通过陷阱,但你会损失陷阱长度只数的蠕虫。
坐在电脑前的你是这款游戏的第一个体验者,你的目标是在至少有一只蠕虫到达终点的前提下,使你消耗的精力值最少。
现在 dodo 对这款游戏进行了简化,在游戏的一开始,你有 n 只蠕虫,在途中一共有 m 的陷阱和 k 只猫咪,每个陷阱和猫咪有一个位置 di(位置两两不同)。你从第一个猫咪或陷阱出发直到最后一个猫咪或陷阱结束游戏。你可以选择一些猫咪并把她吃掉来得到 x 只蠕虫的收益,但每吃掉一只猫咪你需要消耗 ei 点的精力值。对于每一个陷阱,给出陷阱的长度 li,在陷阱前,你可以通过将蠕虫叠起来来通过陷阱,但你会损失陷阱长度只数的蠕虫。
坐在电脑前的你是这款游戏的第一个体验者,你的目标是在至少有一只蠕虫到达终点的前提下,使你消耗的精力值最少。
输入
第一行有四个正整数 n,m,k,x ,分别表示蠕虫只数、陷阱个数、猫咪只数和吃掉一只猫咪的收益个数,每个数由一个空格隔开。
接下来有m行,每行有两个正整数 di,li,分别表示陷阱位置和长度,每个数由一个空格隔开。
接下来有k行,每行有两个正整数 di,ei ,分别表示猫咪位置和消耗能力值,每个数由一个空格隔开。
接下来有m行,每行有两个正整数 di,li,分别表示陷阱位置和长度,每个数由一个空格隔开。
接下来有k行,每行有两个正整数 di,ei ,分别表示猫咪位置和消耗能力值,每个数由一个空格隔开。
输出
输出只有一行,表示消耗最少的精力值。如果无论如何蠕虫都到达不了终点,请输出-1。
提示
对于全部的数据满足,1≤n,m,k,x≤2×105,1≤li,ei≤103,1≤di≤106。
题解
这题问了hy,直接回我仨字,sb题。把猫放入小根堆,遇到陷阱时,如果过不去,就从小根堆中拿猫吃(猫咪辣么可耐,为什么要吃猫猫呢~)。
1 #include<queue> 2 #include<vector> 3 #include<cstdio> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 const int N = 400009; 8 typedef long long LL; 9 struct CPA 10 { 11 LL d, v; 12 bool operator < (const CPA&a) 13 const 14 { 15 return d < a.d; 16 } 17 }g[N]; 18 int m, k, t; 19 LL n, p, ans; 20 priority_queue<LL, vector<LL>, greater<LL> >q; 21 int main() 22 { 23 scanf("%lld%d%d%lld", &n, &m, &k, &p); 24 for(int i = 1; i <= m; i++) 25 { 26 ++t; 27 scanf("%lld%lld", &g[t].d, &g[t].v); 28 g[t].v = - g[t].v; 29 } 30 for(int i = 1; i <= k; i++) 31 { 32 ++t; 33 scanf("%lld%lld", &g[t].d, &g[t].v); 34 } 35 sort(g+1, g+t+1); 36 for(int i = 1; i <= t; i++) 37 { 38 if(g[i].v <= 0) n += g[i].v; 39 else q.push(g[i].v); 40 while(n <= 0 && !q.empty()) 41 { 42 n += p; 43 ans += q.top(); 44 q.pop(); 45 } 46 if(n <= 0) break; 47 } 48 if(n <= 0) puts("-1"); 49 else printf("%lld\n", ans); 50 return 0; 51 }