Учитывая массив, все чей элементы являются положительными числами, найдите максимальную сумму подпоследовательности с ограничением, что числа № 2 в последовательности должны быть смежными в массиве. Так 3 2 7 10 должен возвратиться 13 (сумма 3 и 10), или 3 2 5 10 7 должен возвратиться 15 (сумма 3, 5 и 7).
Я попробовал его с помощью всех возможных позволенных сумм и затем найдя максимум (метод решения "в лоб"), но являюсь там любым лучшим методом. Например, для [3 2 7 10] я суммирую 3,7 и 2,10 и беру максимум.
Больше примеров:
Эта проблема может быть решена динамическим программированием.
Допустим, у нас есть массив целых чисел:
i[1], i[2], i[3], ..., i[n], i[n+1], i[n+2]
Мы разбиваем массив на две части: первая часть, содержащая первые n целых чисел, а вторая часть - это последние два целых числа:
{i[1], i[2], i[3], ..., i[n]}, {i[n+1], i[n+2]}
Давайте обозначаем M_SUM (n)
как максимальная сумма первых n целых чисел на ваше требование.
Там будет два случая:
I [n]
не учитывается в m_sum (n)
, затем m_sum (n + 2) = m_sum (n) + max (i [n + 1], i [n + 2])
I [N]
считается в m_sum (n)
, затем m_sum (n + 2) = m_sum (n) + i [n + 2]
затем, m_sum (n + 2)
, значение, которое мы стремимся, будет большее значение из вышеупомянутых двух.
Тогда мы можем иметь очень наивный псевдокод, что и ниже:
function M_SUM(n)
return MAX(M_SUM(n, true), M_SUM(n, false))
function M_SUM(n, flag)
if n == 0 then return 0
else if n == 1
return flag ? i[0] : 0
} else {
if flag then
return MAX(
M_SUM(n-2, true) + i[n-1],
M_SUM(n-2, false) + MAX(i[n-1],i[n-2]))
else
return MAX(M_SUM(n-2, false) + i[n-2], M_SUM(n-2, true))
}
«Флаг» означает «Разрешить использование последнего целого числа»
Этот алгоритм имеет экспоненциальную сложность времени.
Динамические методы программирования могут быть использованы для устранения ненужного пересчета M_SUM.
Хранение каждого m_sum (n, flag)
в матрицу n * 2. В рекурсионной части, если такое значение не присутствует в матрице, вычислить его. В противном случае просто сделайте значение из матрицы. Это уменьшит временную сложность в линейный.
Алгоритм будет иметь o (n) временную сложность, а o (n) пространство сложности.
F # Решение:
let rec maxsubset = function
| [] -> 0
| x::[] -> x
| x::y::xs -> max (maxsubset (y::xs)) (x + maxsubset xs)
Легко адаптируется к C-подобным языкам:
using System;
using System.Linq;
namespace Juliet
{
class Program
{
static int MaxSubset(int[] arr, int offset)
{
if (offset >= arr.Length)
return 0;
else
return Math.Max(MaxSubset(arr, offset + 1), arr[offset] + MaxSubset(arr, offset + 2));
}
static void Test(params int[] nums)
{
Console.WriteLine("----------------");
Console.WriteLine("MaxSubset({0}) = {1}", String.Join(", ", nums), MaxSubset(nums, 0));
}
static void Main(string[] args)
{
Test(3, 2, 7, 1);
Test(6, 2, 1, 4);
Test(8, 9, 5, 1);
Test(29, 77, 16);
Test(29, 44, 16);
Test(239, 2, 3, 111, 1, 4, 546, 4, 3);
Test(100, 1, 1, 100);
Console.ReadLine();
}
}
}
sum[0] = 0;
sum[1] = 0;
for(i = 0; i < arraylength; i++)
sum[i & 1] += array[i];
printf("sum = %u\n", MAX(sum[0], sum[1]));
printf("homework completed\n");
Симпатичная проблема. Самый простым подходом, кажется, следует учитывать итеративно, поддерживая две лучшие суммы: лучшая сумма, которую вы можете получить при использовании [I], допускается, и лучшая сумма, которую вы можете получить при использовании [i] MinueN т быть допускается. В Python:
def best(arr):
# best sums of zero length array are 0
ok, bad = 0,0
for x in arr:
# best sum if we can use x is to use it,
# because all elements are positive
ok += x
# moving along one step means we can't
# use the ok sum, and can use the bad sum
bad, ok = ok, bad
# but just because we could use ok, doesn't
# mean we have to, so if it's better, use
# that path
if bad < ok:
bad = ok
# bad is then our best possible sum
return bad
int findSum(int* arr, int sz)
{
if( sz <= 0) return 0;
if( sz == 1)
{
return arr[0];
}
else
{
int a = arr[0] + findSum(arr+2, sz-2);
int b = findSum(arr+1, sz-1);
if( a >= b)
return a;
else
return b;
}
}
Позвольте мне попробовать еще раз....
CREATE FUNCTION saneDecimal(@input decimal(5,2)) returns varchar(10)
AS
BEGIN
DECLARE @output varchar(10)
SET @output = CAST(@input AS varchar(10))
DECLARE @trimmable table (trimval char(1))
INSERT @trimmable VALUES ('0')
INSERT @trimmable VALUES ('.')
WHILE EXISTS (SELECT * FROM @trimmable WHERE trimval = CAST(SUBSTRING(@output, LEN(@output), 1) AS char(1)))
SET @output = LEFT(@output, LEN(@output) - 1)
RETURN @output
END
GO
SELECT dbo.saneDecimal(1.00)
-121--3107607- Возможно, более подходящим является рингбуфер. Это не список, хотя вполне вероятно, что он может вести себя достаточно, как список для ваших целей.
Проблема заключается в том, что эффективность сдвига в списке равна O (n), что становится значительным для достаточно больших списков.
Переключение в рингбуфере - это просто обновление местоположения головки, которое равно O (1)
-121--580102-Рассмотрим средний элемент, он может быть частью решения или нет. Для каждого случая найдите лучшие решения для левого и правого оставшихся подперечислять и объедините их, затем выберите лучшее из двух случаев.
Python, шесть строк, использующих динамическое программирование ( не совсем! См. Редаж ниже. ):
def run(x):
if len(x) == 0:
return 0
elif len(x) <= 2:
return max(x)
return max(x[0] + run(x[2:]), x[1] + run(x[3:]))
Редактирование и откат: Хотя решение выше генерирует правильный ответ, это не ] Динамическое программирование. Ниже приведен ниже, и он использует меньше функциональных вызовов:
def main(x):
return max(helper(x))
def helper(x):
if len(x) == 1:
return (0, x[0])
a, b = helper(x[:-1])
return (max(a, b), x[-1] + a)
{
int a[10]={1,2,3,4,5,6,7,89,8,9};
int k=0,i,j,l;
int sum[36],max;
for (i=0;i<10;i++)
{
for (j=i+2;j<10;j++,k++)
sum[k]=a[i]+a[j];
}
max=a[0];
for(i=0;i<36;i++)
printf("sum[%d] is %d\n",i,sum[i]);
for(l=1;l<36;l++)
{
if(max>sum[l])
continue;
else
max=sum[l];
}
printf("%d is the max sum",max);
}
int choose( int n)
{
if((n==1) || (n==0))
return array[n];
if( n==2)
return array[0];
totalSum += max(choose(n-2), choose(n-3));
}
Макс - это функция, чтобы получить максимум отсутствие из двух.
Для массива «массив», сделайте вызов функции для каждого элемента массива и хранить максимальный результат в другом массиве (скажем, arrayofmax [n])
Возьмем, например, [3,2,5,10,7]
Решение с использованием динамического программирования:
Содержите два массива, как показано в последних двух строках
alt текст http://img44.imageshack.us/img44/4843/newgp.jpg
Ответ будет максимум два значения в последнем столбце (красным жирным шрифтом)
.