您的位置:首页 > 其它

湖南工业大学个人选拔赛第二场 解题报告

2013-04-12 19:52 239 查看
A.连续子串和

贪心题,枚举每一个数字作为结束点。保留前i位的前缀和sum[i],对于第i为结束的合法序列,其值为sum[i]-sum[i-K],sum[i]-sum[i-K-1],...,sum[i]-sum[0],那么我们只需要对每一个 i 保留sum[0]到sum[i-K]的最小值即可。

代码如下:

Problem E

#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;

const int INF = 0x7fffffff;
const int MaxN = 1000005;
int N, K;
int A[MaxN], B[MaxN];
double f[MaxN];

bool Ac(double p) {
double Min = INF;
f[0] = 0;
for (int i = 1; i <= N; ++i) {
f[i] = f[i-1] + A[i]-p*B[i];
}
// 得到seq序列,现在要求一个连续的长度大于K的序列,使得总和大于等于0
for (int i = K; i <= N; ++i) {
Min = min(Min, f[i-K]);
if (f[i] - Min >= 0) {
return true;
}
}
return false;
}

double bsearch(double l, double r) {
double mid, ret;
while (r - l > 1e-8) {
mid = (l + r) / 2;
if (Ac(mid)) {
ret = mid;
l = mid + 1e-8;
} else {
r = mid - 1e-8;
}
}
return ret;
}

int main() {
//    freopen("data.in", "r", stdin);
//    freopen("data.out", "w", stdout);
while (scanf("%d %d", &N, &K) != EOF) {
for (int i = 1; i <= N; ++i) {
scanf("%d", &A[i]);
}
for (int i = 1; i <= N; ++i) {
scanf("%d", &B[i]);
}
printf("%.4f\n", bsearch(0, 1000));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: