uva1451贪心算法,求平均值最大的子序列

//uva1451,0.07s
//贪心算法,求平均值最大的子序列
//数形结合,求最大斜率
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 100005;
int n;
int front[N], s[N];
char c[N];

double aotu(int x1, int x2,int x3, int x4) {
	return (s[x4]-s[x3])*(x2 - x1) - (s[x2] - s[x1])*(x4 - x3);
}

int main()
{
	int i,T,L,rear,a,b,res1,res2; 
	//double t,best;
	scanf("%d", &T);
	while (T--) {
		scanf("%d%d", &n,&L);
		scanf("%s", &c);
		if (n == L) {
			printf("1 %d\n", n);
			continue;
		}
		s[0] = 0;
		for (i = 1; i <= n; i++) {
			s[i] = s[i - 1] + c[i-1]-'0';
		}
		a = b = 0;
		//best = 0.0;
		res1 = 0; res2 = L;
		for (rear = L; rear <= n; rear++) {
			while (b-a>1 && aotu(front[b-2],rear-L,front[b-1],rear-L)<=0)
				b--;//删除凸点,或直线中间一点
			front[b++] = rear - L ;//front队列中加入新点,0起点,rear-front为距离,sum差为序列和
			while (b - a>1 && aotu(front[a],rear, front[a+1],rear)>=0 )
				a++;//front[a]是切点,其后不会再有斜率更小的,因为没有凸点了		
			//从队列前面删除斜率小的,被删除的以后也不会成为最优front;
			//t = (s[rear] - s[front[a]] + 0.0) / (rear-front[a]);
//可能是double的精度有限,找最大斜率t会WA
			i = aotu(res1,res2,front[a],rear);
			if (i > 0 || (i==0 && rear - front[a] < res2 - res1) ) {
				//best = t;
				res1 = front[a];
				res2 = rear;
			}
		}
		printf("%d %d\n", res1+1,res2);//起点+1
	}
	return 0;
}

/*
2
17 5
00101011011011010
20 4
11100111100111110000



7 11
6 9

*/

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值