dp[prenum][pos1][pos2] 表示当之前的个数为prenum时pos1到pos2的最大值
一开始做的时候我增加了一个之前的值是什么颜色的状态,直接内存不够用啊了,最后发现其实在从第一个处理的时候,要么直接消除,要么和之后颜色一样的一起消除,所以可以把颜色这个维度去掉
然后状态转移就是 之前的prnum和pos1个要么直接消除,要么和之后相同的一起消除
AC代码如下:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
struct Node{
int id;
int num;
};
int N;
int dp[210][210][210];
Node node[210];
int tot;
int DFS( int prenum, int pos1, int pos2 ){
if( pos1 > pos2 ){
return 0;
}
if( dp[prenum][pos1][pos2] != -1 ){
return dp[prenum][pos1][pos2];
}
int ans = 0;
int temp = prenum + node[pos1].num;
ans = max( ans, temp * temp + DFS( 0, pos1 + 1, pos2 ) );
for( int i = pos1 + 1; i <= pos2; i++ ){
if( node[i].id == node[pos1].id ){
ans = max( ans, DFS( 0, pos1 + 1, i - 1 ) + DFS( temp, i, pos2 ) );
}
}
return dp[prenum][pos1][pos2] = ans;
}
int main(){
int T, Case = 1;
cin >> T;
while( T-- ){
cin >> N;
tot = 0;
cin >> node[++tot].id;
node[tot].num = 1;
for( int i = 1; i < N; i++ ){
int temp;
cin >> temp;
if( temp == node[tot].id ){
node[tot].num++;
}else{
tot++;
node[tot].id = temp;
node[tot].num = 1;
}
}
memset( dp, -1, sizeof( dp ) );
printf( "Case %d: %d\n", Case++, DFS( 0, 1, tot ) );
}
return 0;
}