问题 Q: 最大的数

题目描述

小明和小红在打赌说自己数学学的好,于是小花就给他们出题了,考考他们谁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\n",t);
46     }
47     return 0;
48 }
View Code

 

posted on 2016-08-23 09:46  椿和湫  阅读(186)  评论(0编辑  收藏  举报

导航