Нам задана сетка N * N. И мы сначала находимся в верхнем левом углу сетки. Каждый квадрат сетки имеет некоторое значение, привязанное к нему, то есть, если кто-то достигает этой площади, он выигрывает сумму денег в долларах, равную стоимости, прикрепленной к квадрату. Теперь правовые шаги - это один шаг вправо или один шаг к основанию. Мы должны достигнуть нижнего правого угла сетки по пути, чтобы мы могли максимизировать сумму выигранных денег. Очевидно, мы должны оставаться внутри сетки и не можем ее покинуть. Я начал эту проблему с жадного подхода, который на каждом шаге мы смотрим на непосредственный правый квадрат и ближайший квадрат ниже занимаемого квадрата, и на каждом шаге выбираем квадрат с более высоким значением. Но это не дает правильного результата все время. Например, в следующей сетке,Как увеличить значение пути?
{ 6, 9, 18, 1 }
{ 2, 10, 0, 2 }
{ 1, 100, 1, 1 }
{ 1, 1, 1, 1 }
здесь мой алгоритм дает максимальный оцененный путь как
6 -> 9 -> 18 -> 1 -> 2 -> 1 -> 1
, который составляет до 37, но мы могли бы заработали больше на пути
6 -> 9 -> 10 -> 100 -> 1 -> 1 -> 1
, который составляет 128. Могли бы вы, пожалуйста, помочь мне в создании подходящего алгоритма? Я еще не закодировал это, потому что это дало бы неправильный результат в любом случае. Я не знаю, как справиться с этой проблемой без грубой силы, которая состояла бы в том, чтобы видеть значения во всех путях, не содержащих квадрат с минимальным значением, а затем находить максимум.
#include <iostream>
#include <queue>
using namespace std;
int main()
{ int n; cin >> n;
int a[n+1][n+1], b[n+1][n+1];
for (int i=0;i<n;i++)
{
for (int j=0;j<n;j++)
{
cin >> a[i][j]; b[i][j]=a[i][j];
}
}
queue <int> q; int u,v,m=0;
q.push(0);q.push(0);
while (q.size()!=0)
{
u=q.front(); q.pop(); v=q.front(); q.pop();
if (v<n-1)
{
m=b[u][v]+a[u][v+1];
if (m>b[u][v+1])
{ b[u][v+1]=m; }
q.push(u);q.push(v+1);
}
if (u<n-1)
{
m=b[u][v]+a[u+1][v];
if (m>b[u+1][v])
{ b[u+1][v]=m; }
q.push(u+1);q.push(v);
}
}
cout << b[n-1][n-1];
return 0;
}
Это классическая проблема, которую можно решить с помощью [динамического программирования] (https://en.wikipedia.org/wiki/Dynamic_programming). Пожалуйста, покажите нам, чего вы достигли в коде. – miensol
@miensol Обратите внимание, что в оригинальном плакате не использовался термин «динамическое программирование», из которого я подозреваю, что он или она не знакомы с понятием, поэтому намек на то, что он может быть решен путем динамического программирования (что само по себе является правильным и полностью действительный) не решает проблему с точки зрения вопроса. – Codor
@ Кодор, вы правы, конечно, я не хотел раскрывать полное решение, так как это, скорее всего, домашнее задание. Поэтому я хотел видеть, что на плакате есть код, который нужно показать. – miensol