UVA10559 方块消除【费用提前计算】
解析
显然这道题重点在于消掉一些块之后会产生一些新的连续的块可以一起消,这个不能想到别的什么做法,可以考虑区间。
不过对于一整坨,你要么把他们全部一起消掉,要么就留着等更多的过来一起消掉,你总不可能把一坨分批消掉吧,明显啊
所以刚开始可以把相同颜色的一段块看成一点(不过我太懒了,最后没有这么写,当然,这不是重点,用表示有个颜色为的方块相连。
用惯常的思路进行考虑,设表示消除区间的得分。
单独消除的状态是很好转移的:。
但如果是保留这一段,然后等着和其它的方块一起消呢?我们发现这个状态难以转移,因为这个区间的得分还与这个区间以外的前面消方块的状态息息相关。如果记录下前面消了哪些,还有哪些,在什么位置之类的相关信息,状态数无疑是巨大的。
类比于之前小球的做法,在之前预先计算得分,我们发现这个似乎也行不通,因为这个得分不再是简单的线性关系,而是二次函数,过去的贡献与现在消去的长度有关。
返回去想到这道题重点在于消掉一些块之后会产生一些新的连续的块可以一起消,对于保留的情况,我们是把留着和之前剩下的一串同色的方块合在一起消,如果这些合并在之前被料到并预先计算了得分,并通过状态转移到现在,那么就可以转移了。
对于状态考虑假设在未来经过一些消除操作后,有个与同色的方块在右边和拼在了一起,的最大得分。
为啥只需要记录,而不用管呢,是因为:
假设中某点未来会与相连。
- 的位置在左边,即,那是不可能的,因为未来会与相连,而挡道了,所以一定是在之间消掉的,没机会往那个区间接触。
- 的位置在右边,即,那么这个状态是个包含关系,和产生的贡献可以通过计算,不用这个时候来操心。
所以:对于状态,无论经过什么操作,到之间只能与到之间的区域相连,而区域可以与之后的的区域相连。
最后得到转移方程:
(和它后面的个同系物同色块相消)
(为前面一个和颜色相同的位置,拿掉,那么和它右边的小伙伴们和拼成了一个更大的连续一串(这里就是上文说到的“在未来经过一些消除操作后”的“一些操作”))
直接有点难做,顺序有点乱,所以写成了记搜的样子。
最后答案是
(好久没写这么长的题解了,好家伙,写了一节课)
参考:《对一类动态规划问题的研究》 徐源盛
►Code View
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define N 205
#define INF 0x3f3f3f3f
#define LL long long
int rd()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f*x;
}
int n,a[N],pre[N],pos[N];
LL f[N][N][N];//f[i][j][k]表示消去[i,j]区间 且j右边还有k个和j颜色相同的块
/*
主体部分是连续的[i,j]区间 没有动过
然后j右边有颜色相同的k块紧接在j后面 他们之间的方块已经消完
*/
void Init()
{
memset(f,0,sizeof(f));
memset(pre,0,sizeof(pre));
memset(pos,0,sizeof(pos));
}
LL dp(int i,int j,int k)
{
if(i>j) return 0;
if(f[i][j][k]) return f[i][j][k];
LL res=dp(i,j-1,0)+(k+1)*(k+1);//和右边一整坨一起消掉
int l=pre[j];
while(l>=i)
{
res=max(res,dp(i,l,k+1)+dp(l+1,j-1,0));//拿掉[l+1,j-1] 相同颜色的又拼到一起了
l=pre[l];
}
return f[i][j][k]=res;
}
int main()
{
int T=rd();
for(int cas=1;cas<=T;cas++)
{
Init();
n=rd();
for(int i=1;i<=n;i++)
{
a[i]=rd();
pre[i]=pos[a[i]],pos[a[i]]=i;
}
printf("Case %d: %lld\n",cas,dp(1,n,0));
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!