Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 11221 | Accepted: 3681 |
Description
FJ wants to build a fence around a contiguous group of these fields in order to maximize the average number of cows per field within that block. The block must contain at least F (1 <= F <= N) fields, where F given as input.
Calculate the fence placement that maximizes the average, given the constraint.
Input
* Lines 2..N+1: Each line contains a single integer, the number of cows in a field. Line 2 gives the number of cows in field 1,line 3 gives the number in field 2, and so on.
Output
Sample Input
10 6 6 4 2 10 3 8 5 9 4 1
Sample Output
6500
Source
前一道题目是求一串数中长度大于L的子序列的最大平均值,后一道题在这个基础上,要求输出序列的头和尾的位置。
先看POJ 2018.
先令前缀和为sum[i].若此时序列结尾为点 i , j < k 且在 k 比 j 处决策更优,则容易推得:
sum[i]-sum[k]/i-k > sum[i]-sum[j]/i-j
此时可以用斜率优化,利用单调队列排除点 j .
#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
const int maxn=100005,inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
const ld pi=acos(-1.0L);
ll sum[maxn],dp[maxn],q[maxn],pos[maxn];
ll returnx(ll j,ll k) {
return j-k;
}
ll returny(ll j,ll k) {
return sum[j]-sum[k];
}
int main() {
int n,i,j,l,h,t;
ll x;
scanf("%d%d",&n,&l);
getchar();
sum[0]=dp[0]=0;pos[0]=-1;
for (i=1;i<=n;i++) {
scanf("%lld",&x);
sum[i]=sum[i-1]+x;
}
h=1;t=0;q[0]=0;
mem0(q);
ll ans=0;
for (i=l;i<=n;i++) {
while (t+1<h&&(sum[i]-sum[q[t+1]])*(i-q[t])>=(sum[i]-sum[q[t]])*(i-q[t+1]))
t++;
dp[i]=sum[i]-sum[q[t]];
pos[i]=q[t];
if (dp[i]*(ans-pos[ans])>dp[ans]*(i-pos[i])) ans=i;
while (t+1<h&&(returny(q[h-1],q[h-2])*returnx(i-l+1,q[h-1])>=returny(i-l+1,q[h-1])*returnx(q[h-1],q[h-2])))
h--;
q[h]=i-l+1;
h++;
}
printf("%lld\n",1000*dp[ans]/(ans-pos[ans]));
return 0;
}
https://icpcarchive.ecs.baylor.edu/external/47/4726.pdf
4726 Average
A DNA sequence consists of four letters, A, C, G, and T. The GC-ratio of a DNA sequence is the
number of Cs and Gs of the sequence divided by the length of the sequence. GC-ratio is important
in gene fnding because DNA sequences with relatively high GC-ratios might be good candidates for
the starting parts of genes. Given a very long DNA sequence, researchers are usually interested in
locating a subsequence whose GC-ratio is maximum over all subsequences of the sequence. Since short
subsequences with high GC-ratios are sometimes meaningless in gene fnding, a length lower bound is
given to ensure that a long subsequence with high GC-ratio could be found. If, in a DNA sequence,
a 0 is assigned to every A and T and a 1 to every C and G, the DNA sequence is transformed into a
binary sequence of the same length. GC-ratios in the DNA sequence are now equivalent to averages in
the binary sequence.
Position Index | 1 0 | 1 1 | 1 2 | 1 3 | 1 4 | 1 5 | 1 6 | 1 7 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
Sequence | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 1 | 0 |
For the binary sequence above, if the length lower bound is 7, the maximum average is 6/8 which
happens in the subsequence [7,14]. Its length is 8, which is greater than the length lower bound 7. If
the length lower bound is 5, then the subsequence [7,11] gives the maximum average 4/5. The length
is 5 which is equal to the length lower bound. For the subsequence [7,11], 7 is its starting index and 11
is its ending index.
Given a binary sequence and a length lower bound L, write a program to fnd a subsequence of the
binary sequence whose length is at least L and whose average is maximum over all subsequences of the
binary sequence. If two or more subsequences have the maximum average, then fnd the shortest one;
and if two or more shortest subsequences with the maximum average exist, then fnd the one with the
smallest starting index.
Input
Your program is to read from standard input. The input consists ofT test cases. The number of test
cases T is given in the frst line of the input. Each test case starts with a line containing two integers
n (1 ≤n ≤ 100;000)and L (1≤ L ≤1;000)which are the length of a binary sequence and a length
lower bound, respectively. In the next line, a string, binary sequence, of lengthn is given.
Output
Your program is to write to standard output. Print the starting and ending index of the subsequence.
#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
const int maxn=100005,inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
const ld pi=acos(-1.0L);
ll sum[maxn],dp[maxn],q[maxn],pos[maxn];
ll returnx(ll j,ll k) {
return j-k;
}
ll returny(ll j,ll k) {
return sum[j]-sum[k];
}
int main() {
int cas;
scanf("%d",&cas);
while (cas--) {
int n,i,j,l,h,t;
char c;
scanf("%d%d",&n,&l);
getchar();
sum[0]=dp[0]=0;
for (i=1;i<=n;i++) {
scanf("%c",&c);
sum[i]=sum[i-1]+c-'0';
}
h=1;t=0;q[0]=0;
mem0(q);
for (i=l;i<=n;i++) {
while (t+1<h&&(sum[i]-sum[q[t+1]])*(i-q[t])>=(sum[i]-sum[q[t]])*(i-q[t+1]))
t++;
dp[i]=sum[i]-sum[q[t]];
pos[i]=q[t];
while (t+1<h&&(returny(q[h-1],q[h-2])*returnx(i-l+1,q[h-1])>=returny(i-l+1,q[h-1])*returnx(q[h-1],q[h-2])))
h--;
q[h]=i-l+1;
h++;
}
ll ans=l;
for (i=l+1;i<=n;i++) {
if (dp[i]*(ans-pos[ans])>dp[ans]*(i-pos[i])||
(dp[i]*(ans-pos[ans])==dp[ans]*(i-pos[i])&&i-pos[i]<ans-pos[ans]))
ans=i;
}
printf("%lld %lld\n",pos[ans]+1,ans);
}
return 0;
}