1.题目要求一个序列中的所有连续子序列和的和。如下:对于序列{0.1, 0.2, 0.3, 0.4},有10个连续子序列: (0.1) (0.1, 0.2) (0.1, 0.2, 0.3) (0.1, 0.2, 0.3, 0.4) (0.2) (0.2, 0.3) (0.2, 0.3, 0.4) (0.3) (0.3, 0.4) (0.4).
2.直接进行暴力计算会超时,需要寻找出出现次数的数学关系。
3.关系如下,数组a[0],a[1],a[2]….a[n-1]共n个数,假设数字a[0]出现的次数times,对即a[0],a[0]a[1],a[0]a[1]a[2]…..不难看出出现了n次,除去包含a[0]序列,我们可以看出a[1]出现的次数为n-1次,然后我们再观察包含a[0]的序列中,a[1]出现了times-1次,那么a[1]出现的次数为times1=times-1+n-1。同样,把序列分为包含a[1]和不包含a[1]d两种情况分析,a[2]出现的次数为times2=times1-2+n-2,以此类推:a[3]出现的次数为times3=times2-3+n-3。
所以转化公式为a[i]出现的次数times[i]=times[i-1]-i+n-i。
通过上述公式,可以在O(n)的时间复杂度内计算出结果。

Given a sequence of positive numbers, a segment is defined to be a consecutive subsequence. For example, given the sequence {0.1, 0.2, 0.3, 0.4}, we have 10 segments: (0.1) (0.1, 0.2) (0.1, 0.2, 0.3) (0.1, 0.2, 0.3, 0.4) (0.2) (0.2, 0.3) (0.2, 0.3, 0.4) (0.3) (0.3, 0.4) (0.4).
Now given a sequence, you are supposed to find the sum of all the numbers in all the segments. For the previous example, the sum of all the 10 segments is 0.1 + 0.3 + 0.6 + 1.0 + 0.2 + 0.5 + 0.9 + 0.3 + 0.7 + 0.4 = 5.0.
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N, the size of the sequence which is no more than 105. The next line contains N positive numbers in the sequence, each no more than 1.0, separated by a space.
Output Specification:
For each test case, print in one line the sum of all the numbers in all the segments, accurate up to 2 decimal places.
Sample Input:
4
0.1 0.2 0.3 0.4
Sample Output:
5.00
AC代码:
[c language=”++”]
//#include<string>
//#include <iomanip>
#include<vector>
#include <algorithm>
//#include<stack>
#include<set>
#include<queue>
#include<map>
//#include<unordered_set>
#include<unordered_map>
//#include <sstream>
//#include "func.h"
//#include <list>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<limits.h>
using namespace std;
int main(void)
{
int n;
scanf("%d", &n);
vector<double> num(n, 0);
for (int i = 0; i < n; i++)
{
scanf("%lf", &num[i]);
}
double ans = 0;
long long times = 0;//需要使用long long,避免溢出
for (int i = 0; i < n; i++)
{//当前数字出现的次数与上一个数字出现的次数有联系,联系为times = times – i + n – i;
times = times – i + n – i;
ans += times*num[i];
}
printf("%.2lf\n", ans);
return 0;
}
[/c]