1402 最大值
题目来源: TopCoder
基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题
收藏
关注
一个N长的数组s,满足以下性质:
1)每个元素都是非负的整数,且s[1]=0;
2)任意两个相邻元素差值的绝对值不大于1,即| s[i]-s[i+1] |<=1;
3)对于部分特殊点xi,要求s[xi]<=ti(这样的特殊点一共M个);
问在以上约束下s[]中的最大值最大可能是多少?
Input
多组测试数据,第一行一个整数T,表示测试数据数量,1<=T<=5
每组测试数据有相同的结构构成:
第一行两个整数N,M,表示s[]的长度与特殊点的个数,其中1<=N<=100000,0<=M<=50.
之后M行,每行两个整数xi与ti,其中1<=xi<=N,0<=ti<=100000,且xi以增序给出。
Output
每组数据一行输出,即数组的可能最大值。
Input示例
3
10 2
3 1
8 1
100000 0
2718 5
1 100000
30 100000
400 100000
1300 100000
2500 100000
Output示例
3
99999
2717
给大家分享一下这个题目。。。毙了狗真是弱在别人提示的情况下还Wa了好多次,好吧,进入正题!
这个需要注意什么,首先一个位置可以是多少受两边的特殊位置影响!但是我们注意!起点是固定的,那么我们从左向右先跑一下,能得到各个节点位置可以最大的值(残缺的),这时我们能知道最右边一个特殊位置的最大值,然后我们从右边的向左更新,取两次计算的最小值。
然后怎么办?算两个特殊点之间每一段可能的最大值!我是分了两种情况,
1.相邻的,需要特判一下 弱卡在这里
2.不相邻那么先对其,然后判断奇偶计算即可。
然后!别忘了特殊点是不是最好的?遍历一下
总共更新一下最大值即可
#include<bits/stdc++.h>
#define input freopen("input.txt","r",stdin)
using namespace std;
int value[55][3];
int main(){
input;
int t,n,m,i,j,k;
scanf("%d",&t);
value[0][0]=1; //初始化第一个固定点s[1]=0; value[0][]代表位置
value[0][1]=0; //value[1][]代表最大限制
value[0][2]=0; //value[2][]代表可以选的最大值
while(t--){
scanf("%d%d",&n,&m);
int t1,t2,num=1;
for(i=1;i<=m;i++){
scanf("%d%d",&t1,&t2);
if(t1==1)continue; //多此一举了去重了一下
value[num][0]=t1;
value[num][1]=t2;
num++;
}
m=num-1;
for(i=1;i<=m;i++){ //这时起点是确定的 从1开始 ,即考虑左边的影响
if(value[i][0]-value[i-1][0]+value[i-1][2]<value[i][1]){
value[i][2]=value[i][0]-value[i-1][0]+value[i-1][2];
}
else{
value[i][2]=value[i][1];
}
}
for(i=m-1;i>=0;i--){ //这时终点是确定的 ,这次 右边的影响,需要更新要最小值
value[i][2]=min(value[i][2],value[i+1][2]+value[i+1][0]-value[i][0]);
}
int ans=0;
for(i=1;i<=m;i++){
//这个是个特别坑的特判,即相邻且只差1的情况!我就是坑死在这的
if(value[i][0]==value[i-1][0]+1&&abs(value[i][2]-value[i-1][2])){
ans=max(ans,max(value[i][2],value[i-1][2]));
continue;
}
int cha=value[i][0]-value[i-1][0]-1; //其他的可以先对其,然后找更高的
cha=cha-abs(value[i][2]-value[i-1][2]);
int key=max(value[i-1][2],value[i][2])+cha/2;
if(cha%2) key++;
ans=max(ans,key);
}
for(i=1;i<=m;i++){ //更新最大位置在特殊点上
ans=max(ans,value[i][2]);
}
cout<<max(ans,value[m][2]+n-value[m][0])<<endl; //最后一段
}
return 0;
}