题解:P2135 方块消除

· · 题解

题目传送门

思路

这道题一看就是区间DP,每消除一个区域的方块,就可以得到 b_i^2 的分数,假设 f_{i,j} 为消除区间 [i,j] 的最高分,那么,对于区域 j ,就有两种决策:

决策1:消除区域 j,那么 f_{i,j}=f_{i,j-1}+b^2_i

决策2:暂时不消除区域 j,与之前的某个同色块连在一起消除,但对于决策2,我们需要清楚知道区间 [i,j-1] 中每一个区域的消除情况,状态数过多,我们可以换一种思路。

决策2会对未来行动产生影响,所以我们可以再加一个维度来假设未来情况。

f_{i,j,k} 表示消除区间 [i,j] 且区域 j 之后有 k 个与区域 j 同色的方块的最大得分,对于区域 j,有以下两种决策:

决策1:消除区域 j 和与之相连的 k 个同色方块,那么 f_{i,j,k}=f_{i-1,j-1,0}+(b_j+k)^2

决策2:暂时不消除区域 j 区域,与之前的某个同色区域连在一起消除。假设区间 [i,j-1] 中与区域 j 同色的区域所在位置为 p,那么 f_{i,j,k}=f_{i,p,k+b_j}+f_{p+1,j-1,0}

综上所述,

边界为 $f_{i,j,k}=0,f_{i,i,k}=(b_i+k)^2$ , 即消除区间 $[i,i]$ 的方块且区域 $i$ 之后有 $k$ 个与区域 $i$ 同色的方案最大得分为 $(b_i+k)^2$。 目标解为 $f_{1,n,0}$ ,即消除区域 $[1,n]$ 的方块且区域 $n$ 后有 $0$ 个与区域 $n$ 同色的方块的最大得分。 ## 代码 ```cpp #include<bits/stdc++.h> using namespace std; int c[55],b[55]; long long f[55][55][1005]; //f[i][j][k]代表消除区间[i,j]的方块且区域j之后(未来)有k个与区域j同色的方块的最大得分 int main(){ int n,s=0; cin>>n; for(int i=1;i<=n;i++)cin>>c[i]; for(int i=1;i<=n;i++)cin>>b[i],s+=b[i]; for(int len=1;len<=n;len++){//枚举阶段 for(int i=1;i+len-1<=n;i++){//枚举状态 int j=i+len-1; for(int k=0;k<=s;k++){//决策1 f[i][j][k]=max(f[i][j][k],f[i][j-1][0]+(b[j]+k)*(b[j]+k)); } for(int p=i;p<j-1;p++){//决策2 if(c[p]==c[j]){ for(int k=0;k<=s;k++){ f[i][j][k]=max(f[i][j][k],f[i][p][k+b[j]]+f[p+1][j-1][0]); } } } } } cout<<f[1][n][0];//输出目标解f[1][n][0]; return 0; } ```