Первое, на что нужно обратить внимание, это то, что текущее состояние не зависит от истории того, откуда мы принимали угощение.Единственное, что нас волнует, это то, сколько раз мы принимали угощение слева и сколько раз мы взяли его справа.
Поэтому состояние можно кодировать всего двумя числами: смещение влево и смещение вправо,
Пусть f(i,j)
будет суммой денег, которую мы можем получить, если не продадим текущий ход.Мы знаем, что там мы уже взяли i+j
объектов из линии, поэтому возраст также равен i+j
.
Поэтому нам просто нужно проверить, какую позицию мы хотим занять, и выбрать лучшую.Хорошо, если мы выберем угощение слева, наша сумма будет
cost * time + f( i + 1 , j ) = cost * (i + j) + f( i + 1 , j )
.
Сумма, если взять справа, имеет очень похожую формулу
cost_right * (i + j) + f( i , j + 1 )
.
Поэтому мы можем знать, f(i+1,j)
и f(i,j+1)
вычислить f(i,j)
.
Что ж, это можно сделать с помощью динамического программирования, сохраняя двумерный массив размером n*n
, в котором хранится либо -1
, если f(i,j)
неизвестно, либо значение f(x,y)
, если оно известно.Затем вы можете просто обновить рекурсивный метод, описанный выше, чтобы фактически сохранить результаты и вернуть решение, если оно уже известно.Если мы посмотрим на ваш пример кода, мы можем изменить его для своевременного выполнения.
int give(int a[],int x,int y,int age)
{
if(dp[x][y]!=-1) return dp[x][y];
if(x==y) return age*a[x];
int answer=max(age*a[x]+give(a,x+1,y,age+1),age*a[y]+give(a,x,y-1,age+1));
dp[x][y]=answer;
return answer;
}
Это всего лишь фрагмент, так как вам нужно исправить граничные условия и создать реальный глобальный массив dp, но я надеюсь, что этого достаточно для начала.