«Динамическое программирование · замечательное состояние конструкции» исключить деревянные блоки

Предупреждение: Данная статья является блоггером оригинал статьи, не могут быть воспроизведены без блоггеров допускается. https://blog.csdn.net/Ronaldo7_ZYB/article/details/91632990

Название Описание

Здесь Insert Picture ОписаниеЗдесь Insert Picture Описание

решение проблемы

безусловно , является диапазоном DP , наиболее интуитивной идея состоит в том, чтобы установить состояние е [ L ] [ р ] F [L] [R] является интервал [ L , р ] [L, R] высокий балл.

Но на будущее среди устранить края исчезновения, и тогда операция будет очень трудно, мы здесь, чтобы перейти к использованию метода расчета стоимости:

Положим е [ L ] [ р ] [ К ] F [L] [R] [к] представляет собой интервал [ L , р ] [L, R] После полной ликвидации, но и устранить р р нужного цвета и р р же К К номеру программы.

Здесь Insert Picture Описание
Мы можем использовать эту картинку, чтобы объяснить это состояние перехода уравнение.

Первый случай, если р р не может быть р - 1 г-1 合并,直接将 [ L , р - 1 ] [l,r-1] 的贡献加上r和右边的k合并以后的贡献。即: е [ L ] [ р ] [ К ] знак равно м Икс ( f [ l ] [ r ] [ k ] , f [ l ] [ r 1 ] [ 0 ] + ( k + 1 ) 2 ) f[l][r][k]=max(f[l][r][k],f[l][r-1][0]+(k+1)^2)
第二种情况,将 [ 1 , r ] [1,r] 中的两边合并,合并以后再用 r r 和右边的某个 k k 合并。此时需要保证 [ 1 , r ] [1,r] 中合并的两端必须颜色相同。即: f [ l ] [ r ] [ k ] = m a x ( f [ l ] [ r ] [ k ] , f [ l ] [ i ] [ k + 1 ] + f [ i + 1 ] [ r 1 ] [ 0 ] ) f[l][r][k]=max(f[l][r][k],f[l][i][k+1]+f[i+1][r-1][0])
для перечисления я, мы должны перечислить каждое из р и той же цветовой точки, мы можем использовать дополнительный p r e i pre_i Это указывает на положение точки г и того же цвета. Таким образом, мы можем избежать бесполезного перечисления.

Этот вопрос откровения является то , что мы , как состояние , когда будущее является неопределенным, и использование соответствующих средств для продвижения и увеличение стоимости одномерного состояния ограничить ответ на этот . Например, вот k К мнимому существование, его роль заключается в расчете затрат заранеечтобы облегчить наш статистический ответ.

Код выглядит следующим образом:

#include <bits/stdc++.h>

using namespace std;
const int N = 300;
int n;
int a[N], last[N], pre[N], f[N][N][N];

int dp(int l,int r,int k)
{
	if (l > r) return 0;
	if (f[l][r][k] > 0) return f[l][r][k];
	if (a[r-1] ^ a[r]) f[l][r][k] = dp(l,r-1,0)+(1+k)*(1+k);//格子r单独和右边的格子消 
	for (int i=pre[r];i>=l;i=pre[i])//枚举每一个和颜色r相同的格子 
	    f[l][r][k] = max(f[l][r][k],dp(l,i,k+1)+dp(i+1,r-1,0));//将i和「r和后面的k合并以后的格子」 合并 
	return f[l][r][k];
}

int main(void)
{
	freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);
	scanf("%d",&n);
	for (int i=1;i<=n;++i) {
		scanf("%d",a+i);
		pre[i] = last[a[i]];//记录「和位置i颜色相同的上一次出现」的格子的位置 
		last[a[i]] = i;
	}
	cout << dp(1,n,0) << endl;
	return 0; 
}

рекомендация

отblog.csdn.net/Ronaldo7_ZYB/article/details/91632990