题目描述
小明和小红在打赌说自己数学学的好,于是小花就给他们出题了,考考他们谁NB,题目是这样的给你N个数
在这n个数之间添加N-1个*或+,使结果最大,但不可以打乱原顺序,请得出这个结果
如
1 3 5
结果是(1+3)*5=20;最大
可以添加若干个括号,但一定要保证配对,但是每两个数之间只可能有一个*或+
数列最前和最后不应有+或乘
小明想赢小红但是他比较笨,请你帮帮他
输入
多组测试数据以EOF结束,每组有一个n(n<10000),然后有n个正整数a[i](1<=a[i]<=20)
输出
输出最大的结果由于结果比较大,结果对10086取余
样例输入
3
1 2 3
3
5 1 2
样例输出
9
15
1 //技巧转化 2 //只用考虑 1 的情况就行了。是 1 的话就将它要么加到它的左边要么加到它的右边(加到 1 两边较小的那个数上,保证乘积最大)。 3 // 其他的情况不用考虑(只要是比 1 大的数相乘都比相加大)。 4 5 #include<stdio.h> 6 #include<string.h> 7 #include<algorithm> 8 using namespace std; 9 int a[10000]; 10 int vis[10000]; 11 12 int main( ) { 13 int n; 14 while(scanf("%d", &n) != EOF) { 15 for(int i = 0; i < n; i ++) 16 scanf("%d", &a[i]); 17 memset(vis, 0, sizeof(a)); 18 if(a[0] == 1) { 19 a[1] += 1; 20 vis[0] = 1; 21 } 22 if(a[n - 1] == 1) { 23 a[n-2] += 1; 24 vis[n-1] = 1; 25 } 26 int t = 1; 27 for(int j = 1; j < n - 1; j ++) { 28 if(a[j] == 1) { 29 vis[j] = 1; 30 int l = j - 1; 31 while(vis[l]) { //找到左边离j最近的坐标 ,因为遍历之后j左边点的值不可能为1 32 l--; 33 }; 34 if(a[l] <= a[j + 1] || a[l] == 2) { 35 a[l] ++; 36 } 37 else 38 a[j + 1] ++; 39 } 40 } 41 for(int k = 0; k < n; k++) { 42 if(!vis[k]) 43 t = (t * (a[k]) % 10086) % 10086; 44 } 45 printf("%d ",t); 46 } 47 return 0; 48 }