2241. house

2241. house

题目描述

奶牛们想建立一个新的城市。它们想建立一条长度为 Len 的主线大街,然后建立 K 条小街,每条小街的尽头有一间房子(小街的其它位置没有房子)。每条小街在主线大街的P_i 处分支, 小街的长度用L_i表示。FJ想知道最远的两个房子之间的距离是多少。

输入

第 1 行: 两个整数 Len 和K,意义如题目描述。
第2…K+1行: 每行两个整数P_i和L_i,对应着一条小街的信息。

输出

输出共一行一个整数,即最远的两个房子之间的距离。

样例输入
【输入样例1】

5 4
5 6
2 2
0 3
2 7

【输入样例2】

5 4
2 4
2 2
2 10
2 7

样例输出
【输出样例1】

16

【输出样例2】

17

数据范围限制
对于30%的数据: 1≤Len≤500;2≤K≤100;1≤L_i≤1,000;
对于60%的数据: 1≤Len≤5,000;2≤K≤5,000;1≤L_i≤1,000,000;
对于100%的数据:1≤Len≤100,000,000;2≤K≤500,000;0≤P_i≤Len;1≤L_i≤100,000,000;

提示
【样例1解释】主线大街长度是5,有4条小街,分别位于距离主线大街 0、2、 2、 5 处。这4条小街的长度分别是3、 2、 7、 6。注意:主线大街的同一个地点可以有多条小街;房子 #1 和房子 #4 的距离最远,最远距离是16。

60分:

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
using namespace std;
const int MAX=2147483647;
const int N=1e6;
long long maxx,len,k,p[500010],l[500010];
void input()
{
	scanf("%lld%lld",&len,&k);
	for(int i=1;i<=k;i++) scanf("%lld%lld",&p[i],&l[i]);
}
int main()
{
	fre(house);
	input();
	for(int i=1;i<k;i++)
	for(int j=i+1;j<=k;j++)
		maxx=max(abs(p[i]-p[j])+l[i]+l[j],maxx);
	printf("%lld",maxx);
	return 0;
}

100分:
我们其实只是在60分的基础上减掉了一些多余的排列。
先讲讲做法吧!
设ans(i,j)表示选第i间房子和第j间房子的距离,其他出现的变量同60分做法。
普通的思路:
ans(i,j)=l[i]+l[j]+abs(p[i]-p[j]);
我们做一遍从小到大的排序:
即可去掉绝对值
ans(i,j)=l[i]+l[j]+p[i]-p[j];
然后合并一下:
ans(i,j)=l[i]+p[i]+(l[j]-p[j]);

最后的答案就等于max(ans(i,j));
要使答案最大,那么ans(i,j)就要尽可能大。
然后就可以解决一些多余的运算了。

解释一下为什么
在这里插入图片描述
我们本来是,要选了红点(右边),那我们再用用其他点与它相加取max,但一定要这样吗,其实不用,我们看,如果再到了另一个红点(左边),然后如果都是选蓝点,那肯定是选左边的啦。那大家可能会有疑问,那我们要不要取红点右边的值,其实不用。因为我们反过来思考就行了,大家仔细酝酿(有点dp的思想)。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
using namespace std;
const int MAX=2147483647;
const int N=1e6;
int max1,max2,len,k;
struct node
{
	int p,l;
} a[500010];
void input()
{
	scanf("%d%d",&len,&k);
	for(int i=1;i<=k;i++) scanf("%d%d",&a[i].p,&a[i].l);
}
bool cmp(node x,node y) {return x.p<y.p;}
int main()
{
	fre(house);
	input();
	sort(a+1,a+1+k,cmp);
	max2=a[1].l-a[1].p;
	for(int i=1;i<=k;i++)
	{
		max1=max(max2+a[i].p+a[i].l,max1);
		max2=max(max2,a[i].l-a[i].p);
	}
	printf("%d",max1);
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值