问题背景
shifen广告消费预估系统可以估计出一段时间内一个特定的广告在检索结果中排在各个位置的几率。比如系统对某广告的输出如下:
p
1 = 0.03, p
2 = 0.08, p
3 = 0.04 ……
这说明该广告展现在第1位的概率是 3%,展现在第2位的概率是 8%,展现在第3位的概率是 4%……
问题是:如何给出一个 排名估计区间 [i, j],使得广告出现在该区间中的概率大于或等于一个预设值p,同时这个区间所包含的元素尽可能的少。也可用数学语言来描述:给定数p和数列 p 1, p 2, … , p n,求 i和 j (1 <= i <= j <= n),在满足p i + p i+1 + … + p j >= p的前提下让j-i 最小。
一般来说,p i只需保留6位小数就足够了。这样,若令a i=10 6p i,a=10 6p,则a和所有的a i均为[0,10 6]之间的整数。这样就避免了对实数的处理。
输入格式
第一行包含一个整数n (1 <= n <= 100,000)。
以下n行每行包含一个[0,10 6]内的整数,依次为a 1,a 2,…,a n。 这 n 个整数之和保证不超过 106 。
最后一行包含一个[0,10 6]内的整数a。 保证所有 ai 之和不小于 a 。
以下n行每行包含一个[0,10 6]内的整数,依次为a 1,a 2,…,a n。 这 n 个整数之和保证不超过 106 。
最后一行包含一个[0,10 6]内的整数a。 保证所有 ai 之和不小于 a 。
输出格式
输出仅一行,包含一个整数,即j – i的最小值。
样例输入
7
5
8
4
7
10
5
2
18
5
8
4
7
10
5
2
18
样例输出
2
样例解释
a
2=8, a
3=4, a
4=7之和为19,满足条件。而任何两个相邻数之和均小于18。
解题思路
这个问题只要弄明白题目的模型就会很容易了,最关键的是大数据量问题,即对于一百万个数据的用例进行测试的时候能否在1秒钟内运行完毕的问题。
基本的解题思想是:把每一串相邻数字进行运算,先比较所有长度为2的相邻串,再比较长度为3的相邻串.....依次进行下去,当发现一个相邻串的和>=给定的a时,就将相邻串的“长度-1”输出,即为结果。
下面示例代码主要是优化了重复做加法的过程,用一个长度为n的total数组的空间开销来换取重复累加的运算。
示例代码
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
int main(void)
{
int n(0);//个数
int i(0),j(0);//循环
int threash(0);//阈值
int *data=NULL;//存数
int *total=NULL;//存累加和
scanf("%d",&n);
data = new int[n];
total = new int[n];
for (i=0;i<n;i++)
{
scanf("%d",&data[i]);
}
memcpy(total,data,sizeof(int)*n);
scanf("%d",&threash);//
for (i=1;i<n;i++)//i表示相隔几个
{
for (j=0;j<n-i;j++)//对每一个相邻链求和
{
total[j] = total[j] + data[j+i];
if (total[j]>=threash)
{
printf("%d/n",i);
return 0;
}
}
}
//其实不应该执行到这里
return 0;
}