一个N长的数组s[](注意这里的数组初始下标设为1,而不是0,即N个元素为s[1],s[2],...,s[N]),满足以下性质:
1)每个元素都是非负的整数,且s[1]=0;
2)任意两个相邻元素差值的绝对值不大于1,即| s[i]-s[i+1] |<=1;
3)对于部分特殊点xi,要求s[xi]<=ti(这样的特殊点一共M个);
问在以上约束下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
nm算法可以过。先初始化a[i] = i-1 ,每输入一个一个xi 和 ti 就更新下a数组。当然也有O(n)和O(m)算法,
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 1e5+10; 4 int a[N], t, n, m, xi, ti; 5 int main() { 6 ios::sync_with_stdio(false); 7 cin >> t; 8 while(t--) { 9 cin >> n >> m; 10 for(int i = 1; i <= n; i ++) a[i] = i-1; 11 for(int i = 0; i < m; i ++) { 12 cin >> xi >> ti; 13 if(ti >= xi-1) continue; 14 if(a[xi] > ti) { 15 int j = 0; 16 while(xi+j <= n) { 17 if(a[xi+j] > ti+j) { 18 a[xi+j] = ti+j; 19 } 20 j++; 21 } 22 j = 1; 23 while(xi-j >= 1) { 24 if(a[xi-j] > ti+j) { 25 a[xi-j] = ti+j; 26 } 27 j++; 28 } 29 } 30 } 31 int MAX = -1; 32 for(int i = 1; i <= n; i ++) MAX = max(MAX, a[i]); 33 printf("%d ",MAX); 34 } 35 return 0; 36 }