P2135
方块消除
题目描述
Jimmy 最近迷上了一款叫做方块消除的游戏。游戏规则如下:\(n\) 个带颜色方格排成一列,相同颜色的方块连成一个区域(如果两个相邻方块颜色相同,则这两个方块属于同一区域)。为简化题目,将连起来的同一颜色方块的数目用一个数表示。
例如,9 122233331 表示为
4
1 2 3 1
1 3 4 1
游戏时,你可以任选一个区域消去。设这个区域包含的方块数为 \(x\),则将得到 \(x^2\) 个分值。方块消去之后,其余的方块就会竖直落到底部或其他方块上。而且当有一列方块被完全消去时,其右边的所有方块就会向左移一格。Jimmy 希望你能找出得最高分的最佳方案,你能帮助他吗?
输入格式
第一行包含一个整数 \(m\)(\(1 \le m \le 50\)),表示同颜色方块区域的数目。
第二行包含 \(m\) 个数,表示每个区域的颜色(\(1\) 到 \(m\) 之间的整数)。
第三行包含 \(m\) 个数,表示每个区域包含的方块数(\(1\) 到 \(20\) 之间的整数)。
输出格式
仅一个整数,即最高可能得分。
样例 #1
样例输入 #1
4
1 2 3 1
1 3 4 1
样例输出 #1
29
f[l][r][cnt]:l~r r后面接了cnt个与color[r]相同颜色的方块
两种决策:
1.直接消掉len[r]+cnt
2.在l~r-1中找一个与color[r]相同颜色的i 将i+1~r-1消掉后再将l~i消掉 此时后面接的变为len[r]+cnt+len[i]
用记忆化搜索实现可以更好的对初始值 边界情况进行处理
点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n,a[55],b[55],f[205][205][205];
int c[55];
int dp(int l,int r,int cnt)//l~r r后面接了cnt个跟color[r]相同颜色的方块
{
int tot=b[r]+cnt;
if(l==r)return tot*tot;
if(f[l][r][cnt])return f[l][r][cnt];
int maxx=dp(l,r-1,0)+tot*tot;
for(int i=l;i<r;i++)
if(a[i]==a[r])
maxx=max(maxx,dp(i+1,r-1,0)+dp(l,i,tot));
return f[l][r][cnt]=maxx;
}
int main()
{
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)cin>>b[i];
cout<<dp(1,n,0)<<"\n";
return 0;
}
此生无悔入OI 来生AK IOI

浙公网安备 33010602011771号