最大连续子序列乘积(小米手机2013年校园招聘笔试题)
- 题目描述:
- 给定一个浮点数序列(可能有正数、0和负数),求出一个最大的连续子序列乘积。
-
- 输入:
-
输入可能包含多个测试样例。
每个测试样例的第一行仅包含正整数 n(n<=100000),表示浮点数序列的个数。
第二行输入n个浮点数用空格分隔。
输入数据保证所有数字乘积在双精度浮点数表示的范围内。
- 输出:
-
对应每个测试案例,输出序列中最大的连续子序列乘积,若乘积为浮点数请保留2位小数,如果最大乘积为负数,输出-1。
- 样例输入:
-
7 -2.5 4 0 3 0.5 8 -1 5 -3.2 5 -1.6 1 2.5 5 -1.1 2.2 -1.1 3.3 -1.1
- 样例输出:
-
12 64 8.78
状态dpMax[i]表示以arr[i]结尾的最大连续子串乘积值,dpMin[i]表示以arr[i]结尾的最小连续子串乘积值(考虑到负数的情况)。
状态转移方程: dpMax[i]=maxVal(arr[i],arr[i]*dpMin[i-1],arr[i]*dpMax[i-1]);
dpMin[i]=minVal(arr[i],arr[i]*dpMin[i-1],arr[i]*dpMax[i-1]);
Code:
#include <cstdio> using namespace std; void initDp(double dp[],int length){ for(int i=0;i<length;++i) dp[i]=0; } double maxVal(double a,double b,double c){ return a>b?(a>c?a:c):(b>c?b:c); } double minVal(double a,double b,double c){ return a<b?(a<c?a:c):(b<c?b:c); } const int arrSize=100010; double arr[arrSize],dpMin[arrSize],dpMax[arrSize]; int main() { int n; while(scanf("%d",&n)!=EOF){ for(int i=0;i<n;++i) scanf("%lf",&arr[i]); initDp(dpMin,n); initDp(dpMax,n); if(n==1&&arr[0]<0){ printf("%d\n",-1); continue; } dpMin[0]=dpMax[0]=arr[0]; for(int i=1;i<n;++i){ dpMax[i]=maxVal(arr[i],arr[i]*dpMin[i-1],arr[i]*dpMax[i-1]); dpMin[i]=minVal(arr[i],arr[i]*dpMin[i-1],arr[i]*dpMax[i-1]); } double answer=0; for(int i=0;i<n;++i){ if(dpMax[i]>answer) answer=dpMax[i]; } double tmp=answer-(int)answer; if(tmp==0) printf("%d\n",(int)answer); else printf("%.2lf\n",answer); } return 0; } /************************************************************** Problem: 1501 User: lcyvino Language: C++ Result: Accepted Time:120 ms Memory:3864 kb ****************************************************************/