Название Описание
решение проблемы
безусловно , является диапазоном DP , наиболее интуитивной идея состоит в том, чтобы установить состояние является интервал высокий балл.
Но на будущее среди устранить края исчезновения, и тогда операция будет очень трудно, мы здесь, чтобы перейти к использованию метода расчета стоимости:
Положим представляет собой интервал После полной ликвидации, но и устранить нужного цвета и же номеру программы.
Мы можем использовать эту картинку, чтобы объяснить это состояние перехода уравнение.
Первый случай, если
не может быть
合并,直接将
的贡献加上r和右边的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;
}