Mooo

news/2024/11/21 1:44:41/

【题目描述】

  有 N 个能量发射站排成一行,每个发射站i都有不相同的高度 Hi,并能向两边(当然两端的只能向一边)同时发射能量值为 Vi 的能量,并且发出的能量只被两边最近的且比它高的发射站接收。

  显然每个发射站有可能接收 0 或 1 或 2 个其它发射站发来的能量,特别是为了安全,它受到的能量总和是我们很关心的。由于数据很多,请你帮助我们计算出接受了最多能量的发射站接受的能量是多少。

【数据范围】

1 <= N <= 50,000

1 <= hi <= 2,000,000,000

1 <= vi <= 10,000

【输入格式】

第1行: 一个整数 N

第2..N+1行:第 i+1 行有2个整数 Hi Vi,表示第i个发射站的高和发射的能量值。

【输出格式】

一行:一个发射站接收到的最大能量值。

【样例输入】

3
4 2
3 5
6 10

【样例输出】

7


蒟蒻表示还是不会

怎么办呢?

随机枚举信号塔求此塔的接收值+卡时

。。。。。。

然后居然又A了

RP已败光。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
using namespace std;
int m;
int z,ans;
struct self{int x,y;}s[50555]; //high->x  power->y
int a,b,c;
int tall,num;
bool flag[50555];void eixt()
{cout<<z<<'\n';
}void work(int i)
{ans=0;int a,b,lt,rt;lt=rt=0;for(a=i-1;a>=1;a--){if(s[a].x>=s[i].x)break;if(s[a].x>=lt){ans+=s[a].y;lt=s[a].x;}}for(b=i+1;b<=m;b++){if(s[b].x>=s[i].x)break;if(s[b].x>rt){ans+=s[b].y;rt=s[b].x;}}z=max(z,ans);
}int main()
{freopen("mooo.in","r",stdin);freopen("mooo.out","w",stdout);scanf("%d",&m);for(a=1;a<=m;a++){scanf("%d%d",&s[a].x,&s[a].y);if(s[a].x>tall){tall=s[a].x;num=a;}}flag[num]=1;work(num);while((double)clock()/CLOCKS_PER_SEC<=0.91){ans=0;a=(rand()+rand())%m+1;while(flag[a]){a=(rand()+rand())%m+1;if((double)clock()/CLOCKS_PER_SEC>=0.93){eixt();return 0;}}flag[a]=1;work(a);}eixt();return 0;
}



正解是单调队列或者单调栈吧

还要ORZ XPF大神


我们可以先考虑向左发射信号

再考虑向右发射信号


用一个栈维护i前(或后)的第一个比h[i]高的塔的编号

先考虑向左发射的情况

对于栈顶top对应的ht和wt

如果当前i站的hi=>ht则需要找到第一个比hi大的ht 需要top-- 

因为stack的push是从前向后的 所以第一个满足ht>hi的top肯定是i前面第一个比h大的站

l[stack[top]]+=s[i].w; 同时i进栈


如果当前i站的hi<ht 表示i前的最低高度大于hi  t站可以接收到i的信号

此时只需将i进栈 l[stack[top]]+=s[i].w;


正着一遍 反着一遍 ans=max(ans,l[i]+r[i]);

#include<iostream>
#include<cstdio>
using namespace std;
const int lim=50555;
int stack[lim];
int top;int l[lim],r[lim];struct self{int h,w;}s[lim];
int m,a,b,c;void left()
{int a,b;top=1;stack[1]=1;for(a=2;a<=m;a++){if(s[stack[top]].h>s[a].h){l[stack[top]]+=s[a].w;top++;stack[top]=a;}else{while(s[stack[top]].h<=s[a].h&&top>0)top--;if(top>=1)l[stack[top]]+=s[a].w;top++;stack[top]=a;}}
}void right()
{int a,b;top=1;stack[1]=m;for(a=m-1;a>=1;a--){if(s[stack[top]].h>s[a].h){l[stack[top]]+=s[a].w;top++;stack[top]=a;}else{while(s[stack[top]].h<=s[a].h&&top>0)top--;if(top>=1)l[stack[top]]+=s[a].w;top++;stack[top]=a;}}
}void print()
{int a,ans=0;for(a=1;a<=m;a++)ans=max(ans,l[a]+r[a]);cout<<ans<<'\n';
}int main()
{freopen("mooo.in","r",stdin);freopen("mooo.out","w",stdout);scanf("%d",&m);for(a=1;a<=m;a++)scanf("%d%d",&s[a].h,&s[a].w);left();right();print();return 0;
}





http://www.ppmy.cn/news/690023.html

相关文章

mood

心情不好

demo.

Demo源代码 <?php header(X-XSS-Protection: 0); $xss isset($_GET[xss])? $_GET[xss] : ; $xss str_replace(array("(",")","&","\\","<",">",""), , $xss); echo "<img sr…

ADMM

背景知识 对偶上升 等式约束优化问题&#xff1a; f f f是凸函数&#xff0c;2.1的拉格朗日项为&#xff1a; 其对偶函数为&#xff1a; inf代表下确界&#xff0c;之所以用下确界而不是用min&#xff0c;可能是因为有些函数没有极值&#xff08;定义域取不到&#xff09…

TO moya

谢谢你在我的BLOG上面的回复&#xff01;关于你说的"使用Netmeeting SDK"实现点对点的通信其实是很简单的。打开一个记事本&#xff0c;拷贝如下的代码&#xff1a; <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html> &…

momo

momo.lic 文件 d65b5dc791cc1825c13349d46c011429

7-4 jmu-Java-05集合-4-倒排索引

对若干行文字建立倒排索引(根据单词找到所在行号)。 然后根据关键字&#xff0c;在倒排索引查找进行查找&#xff0c;找到包含所有该关键字所在的行数并输出。 输入说明 若干行英文&#xff0c;以!!!!!为结束。输入一行查询关键字&#xff0c;以1个空格为分隔 输出说明 输出…

damo10

放大镜效果 需求&#xff1a; 1.鼠标移至图片上方&#xff0c;鼠标周围出现黄色的的正方形框&#xff0c;黄色矩形框会随着鼠标的移动而移动&#xff1b; 2.将黄色正方形框里的内容的长和宽均放大2.4倍&#xff0c;并在图片右边进行显示。 实现原理&#xff1a; 获得鼠标在盒子…

damo2

轮播图 需求: 1.鼠标不在图片上方时&#xff0c;进行自动轮播&#xff0c;并且左右箭头不会显示&#xff1b;当鼠标放在图片上方时&#xff0c;停止轮播&#xff0c;并且左右箭头会显示&#xff1b; 2.图片切换之后&#xff0c;图片中下方的小圆点会同时进行切换&#xff0c;并…