您的位置:首页 > 其它

UVa 1451 Average——斜率优化

2017-06-05 18:42 393 查看
思路紫书上写的就很好,这里只强调一点:

注意要求的斜率是(Sj - Si-1)/(j - i + 1),一定要注意这个i-1,假如想得到前三个数的平均值,在图上就要从0开始,求0到3的平均值,而不是1到三的平均值。

说的有点抽象,还请读者琢磨一下代码里的+1-1的问题

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int maxn = 100000 + 10;

int n, L, s[maxn], node[maxn];
char str[maxn];

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

void solve() {
s[0] = 0;
for (int i = 1; i <= n; i++) {
s[i] = s[i - 1] + str[i] - '0';
}

int i = 0, j = 0;
int ansi = 0, ansj = L;
for (int t = L; t <= n; t++) {
while (j - i > 1 && cross(node[j - 2], t - L, node[j - 1], t - L) >= 0) j--;
node[j++] = t - L;
while (j - i > 1 && cross(node[i + 1], t, node[i], t) >= 0) i++;
int temp = cross(node[i], t, ansi, ansj);
if (temp > 0 || (temp == 0 && t - node[i] < ansj - ansi)) {
ansj = t, ansi = node[i];
}
}
printf("%d %d\n", ansi + 1, ansj);
}

int main()
{
int T; scanf("%d", &T);
while (T--) {
scanf("%d %d", &n, &L);
getchar();
gets(str + 1);
solve();
}
return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: