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;
}
posted @ 2023-01-17 21:13  PKU_IMCOMING  阅读(21)  评论(0)    收藏  举报