acwing322消木块

2023-10-09 23:04
文章标签 acwing322 木块

本文主要是介绍acwing322消木块,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这个题目就当一个见识吧

设f[i][j][k]表示当前的状态是[i,j]并且j后面还有k个与j颜色相同的木块的最大价值

第一种情况,当第j块和第j-1块颜色相同时,f[i][j][k]=f[i][j-1][k+1]

第二种情况,当第j块和第j-1块颜色不同时,考虑最后那一堆颜色相同的怎么消去的

如果这一堆没有跟其他颜色相同的合并,那么对于任意一种操作,我们都可以把消去最后这一堆的子操作放在最开始,即最开始就消掉最后这一堆,而不影响答案,所以我们有 f [ i ] [ j ] [ k ] = f [ i ] [ j − 1 ] [ 0 ] + ( 1 + k ) 2 f[i][j][k]=f[i][j-1][0]+(1+k)^2 f[i][j][k]=f[i][j1][0]+(1+k)2

如果我们要让最后这一堆跟前面的某一堆颜色相同的一起消去,我们不妨设最后第j块与原始序列的第p块挨在了一起

那么我们在消除第j块和第p块这连在一起的一堆之前的操作,一定是分开的,即在[1,p]和[p+1,j-1]这两个区间中间分别进行(因为不能增添木块只能消除),所以我们可以先全部进行[p+1,j-1]这个区间的操作在进行[1,p]这个区间的操作而不影响答案。而且根据以上分析,这个p一定是原始序列某一堆颜色相同的块中最右边的一块,而不会是中间的某一块,所以也就很好枚举了

具体见代码

#include<cstdio>
#include<algorithm>
#include<cstring> 
using namespace std;
const int N=210;
int f[N][N][N],a[N];
void dp(int i,int j,int k)
{if(f[i][j][k]) return;if(i==j) {f[i][j][k]=(1+k)*(1+k);return;}if(a[j]==a[j-1]){/*int l=j-1;while(a[l]==a[j]) l--;if(l==i-1) {f[i][j][k]=(j-i+1+k)*(j-i+1+k);return;}dp(i,l+1,k+j-l-1);f[i][j][k]=f[i][l+1][k+j-l-1];*/dp(i,j-1,k+1);f[i][j][k]=f[i][j-1][k+1];return;//注释的是另一种写法,两种没明显区别//但注释的写法确实要好一点,不用调用多次函数 }for(int l=j-1;l>=i;l--)if(a[l]==a[j]&&a[l+1]!=a[j]){dp(i,l,k+1),dp(l+1,j-1,0);f[i][j][k]=max(f[i][j][k],f[l+1][j-1][0]+f[i][l][1+k]);}dp(i,j-1,0);f[i][j][k]=max(f[i][j][k],f[i][j-1][0]+(1+k)*(1+k));
}
int main()
{int t,cnt=0;scanf("%d",&t);int n;while(t--){memset(f,0,sizeof(f));scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]);dp(1,n,0);cnt++;printf("Case %d: %d\n",cnt,f[1][n][0]);}return 0;
}

洛谷的讨论区好像还有记忆化搜索的优化,可以看一下

这篇关于acwing322消木块的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/176199

相关文章

例题:木块问题(UVa 101)

输入n,得到编号为0~n-1的木块,分别摆放在顺序排列编号为0~n-1的位置。现对这些木块进行操作,操作分为四种。 1、move a onto b:把木块a、b上的木块放回各自的原位,再把a放到b上; 2、move a over b:把a上的木块放回各自的原位,再把a发到含b的堆上; 3、pile a onto b:把b上的木块放回各自的原位,再把a连同a上的木块移到b上; 4、

滑木块H5小游戏

欢迎来到程序小院 滑木块 玩法:点击木块横着的只能左右移动,竖着的只能上下移动,移动到箭头的位置即过关,不同关卡不同的木块摆放,快去滑木块吧^^。 开始游戏https://www.ormcc.com/play/gameStart/260 html <canvas id="c2canvas" width="384" height="600"></canvas> css

nyoj260 数数小木块

数数小木块 时间限制: 3000 ms  |  内存限制: 65535 KB 难度: 1 描述 在墙角堆放着一堆完全相同的正方体小木块,如下图所示:    因为木块堆得实在是太有规律了,你只要知道它的层数就可以计算所有木块的数量了。 现在请你写个程序 给你任一堆木块的层数,求出这堆木块的数量. 输入 第一行是一个整数N(N<=10)表示测试数据的组数)

『动态规划·奇葩状态设计』消木块 Blocks

题目描述 题解 显然是一个区间DP,最直观的思路就是设置状态 f [ l ] [ r ] f[l][r] f[l][r]为区间 [ l , r ] [l,r] [l,r]的最高得分。 但是对于中间消除以后再消边上操作会十分困难,我们这里采用一种费用提前计算的方法: 我们设 f [ l ] [ r ] [ k ] f[l][r][k] f[l][r][k]表示在区间 [ l , r ]