题意:给一排方块,每个方块有一个颜色,每次可以选几个连续颜色相同方块消除,得分为方块数平方,求最大总得分。
按照一般的序列dp思路,dp[i][j]应当从dp[i][k]和dp[k][j]中转移(i<=k<=j),但本题中可能两边都剩下方块一起消,无法转移,状态也不好表示。
我预处理时先用分块的思想,把颜色相同的小块分为一个大块。
所以这个题以[i,j]这个区间中最后一个方块j怎样消除为决策,j可以直接就在当前消除,或者把中间的消除后,和左边一个颜色相同的大块拼起来(这个大块需要枚举).但是注意,和左边某个大块拼起来后,也不一定立即消除,有可能还和左边的左边的一个大块拼起来,所以还需要再开一维,dp[i][j][k]表示j的左边挂着k个和j一个颜色的小块。
看似状态n^3,转移最坏n,但是注意转移时枚举的是大块,一般数据会大大降低时间。还有dp[i][j][k]中的i,j都是大块的端点,每对i,j对应的k也不会很多,所以记搜实际状态数不多(数据组数<=15,980ms)
#include<iostream>
#include<cstdio>
#include<cstring>
#define LL long long
int n,A[500],B[500],L[500],R[500];
bool vis[210][210][210];
LL dp[210][210][210];
using namespace std;
LL Max(LL a,LL b){
if (a>b) return a;
else return b;
}
LL Sq(LL a){return a*a;}
LL Dfs(in