题目大意:给出一段长度为n的数列,数列中的元素有正有负,求一段连续的区间,使得该区间的和的绝对值最接近给定的值
尺取法一般适用于对一段连续的区间的和进行处理的情况,反复推进区间复杂度一般为O(n)
当区间的元素都正整数时,区间和是单调递增的,通过不断向前推进区间的开头s和末尾t来满足题目要求的最优解即为尺取法
另外对于区间的和可以转化为两个前缀和相减的形式:
设sum[i]=a[1]+a[2]+....+a[i],(一般把数组下标设为从1开始比较方便处理)
则区间[s,t]的和=sum[t]-sum[s-1];
而sum[t]-sum[s]为区间[s+1,t]的和,区间的起点下标一定要注意加1;
此题可以把区间和转化为前缀和相减的形式,由于是求区间和的绝对值,所以可以对区间和从小到的进行排序,
(s<t时,abs(sum[t]-sum[s])=abs(sum[s]-sum[t]),与顺序无关),只要用一个pair数组标记一下前缀和的下标即可,
这时由于该区间是单调递增的,就可以采用尺取法处理了,注意每次推进区间前更新一下最优解.
if(sum m) s++;//区间大了else if(sum==m) break;//找到最优解
此题有个比较坑的地方时INF必须开的比2000000000大(0x3f3f3f3f肯定小了),等于或者小余都会wa.
还有一个比较坑的地方时,给定的t可能为0,而区间不能为0,所以推进区间后要进行一下判断
以下是ac代码
/** Created: 2016年04月03日 22时33分15秒 星期日* Author: Akrusher**/#include #include #include #include #include #include #include #include #include #include #include #include #include