最大的数(贪心算法)

描述

小明和小红在打赌说自己数学学的好,于是小花就给他们出题了,考考他们谁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

贪心算法
就是向左贪心。从左至右,遇到第i个数,选择当时最好的方案(*或+),用子问题(前i-1个数的最大值)来∗/+

第i个数,从而得到最新子问题(前i个数的最大值)。只是在下面的一些特殊情况下,要另外处理。

一般情况下,相乘比相加得到的数值大。所以,一般用乘法。但是也有特殊情况,那就1和2。

对于数值1,1*a=a ,但是1+a=a ,所以遇到1时我们要用加法,而不是乘法。
但是,是让1加他左边的数,还是让1加他右边的数呢?
这就要讨论了。对于 a 1 b 。 当a<b,(a+1)∗b>(b+1)∗a

,所以选择1加a ; 当a>b,(a+1)∗b<(b+1)∗a

,所以选择1加b. 综上,a ,b 哪个小1就加谁。但是,这也不一定完全对。
当a和b相同时,就加a而不加b,因为我们这是向左的贪心算法。
还有一种情况,就不能够“哪个小1就加谁”。

输入数据输出结果
11
1 11+1=2
1 1 11+1+1=3
1 1 1 11+1+1+1 = 2*2 =4
1 1 1 1 13*2 =6 > 5
1 1 1 1 1 1 1 13*3*2 =18 > 8
2 1 1 23*3=9 > 2*2*2=8

从上表可以看出,当全1的个数小于或等于4时 ,加分比乘法优;但是当大于4时,我们会尽可能的“凑3”,3个1相加,3个1相加 这样才能够最优的。
所以1+2 比1+1会得到更好的效果
所以 当有2 1 a 这样时,时,无论a为多少,直接让1与2相加。

当然,第一个数如果为1,他只有右边的数可以加;最后一个数如果为1,他只有左边的数可以加,所以这两种情况要另外讨论。

 

//向左的贪心算法。 
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[10005],b[10005];
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		int i,j;
		for (i=1;i<=n;i++)
			scanf("%d",&a[i]);
		for (i=1,j=1;i<=n;i++)
		{
			if (a[i]!=1)
			{
				b[j] = a[i];
				j++;
			}
			else
			{
				if (i==1)
				{
					if (n==1)
					{
						b[j] = a[i];
						j++;
						break;
					}
					else
					{
						b[j] = a[i] + a[i+1];
						j++;
						i++;
						continue;
					}
				}
				if (i==n || b[j-1]<=a[i+1])
					b[j-1] += a[i];
				else
				{
					if (b[j-1]==2)
						b[j-1] += a[i];
					else
					{
						b[j] = a[i] + a[i+1];
						i++;
						j++;
					}
				}
			}
		}
		int sum = 1;
		for (i=1;i<j;i++)
			sum = (sum * b[i]) % 10086;
		printf("%d\n",sum);
	}
	return 0;
}

 

    原文作者:贪心算法
    原文地址: https://blog.csdn.net/qq_40912854/article/details/81710938
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞