标签:dfs return 方块 题解 len 消除 long dp
题目
题目描述
Jimmy最近迷上了一款叫做方块消除的游戏。游戏规则如下:n个带颜色方格排成一列,相同颜色的方块连成一个区域(如果两个相邻方块颜色相同,则这两个方块属于同一区域)。为简化题目,将连起来的同一颜色方块的数目用一个数表示。
例如,9 122233331表示为
4 1 2 3 1
1 3 4 1
游戏时,你可以任选一个区域消去。设这个区域包含的方块数为x,则将得到x^2个分值。方块消去之后,其余的方块就会竖直落到底部或其他方块上。而且当有一列方块被完全消去时,其右边的所有方块就会向左移一格。Jimmy希望你能找出得最高分的最佳方案,你能帮助他吗?
输入格式
第一行包含一个整数m(1<=m<=50),表示同颜色方块区域的数目。第二行包含m个数,表示每个方块的颜色(1到m之间的整数)。
输出格式
仅一个整数,即最高可能得分。
输入输出样例
输入
4
1 2 3 1
1 3 4 1
输出
29
解析
首先定义状态:dp[l][r][k] 表示从l到r合并起来,同时后面还有k个和这个同色的方块能获取的最大值。
这个需要分情况dp:
首先如果l == r 直接返回(len[r] + k)2 即可
然后直接炸掉后面的,收益就是dp[l][r - 1][0] + (len[r] + k)2
再然后就是正常合并,从l到r枚举断点i,在他本身和dp[l][i][len[r] + k] + dp[i + 1][r - 1][0]取最大值
代码
#include<bits/stdc++.h>
using namespace std;
long long co[10001];
long long len[100001];
long long n;
long long dp[101][101][301];
long long dfs(long long l,long long r,long long k){
if(l > r) return 0;
if(l == r) return dp[l][r][k] = (len[r] + k) * (len[r] + k);
if(~dp[l][r][k]) return dp[l][r][k];
dp[l][r][k] = (len[r] + k) * (len[r] + k) + dfs(l,r - 1,0);
for(int i = l; i < r; i++){
if(co[i] == co[r]) dp[l][r][k] = max(dp[l][r][k],dfs(l,i,len[r] + k) + dfs(i + 1,r - 1,0));
}
return dp[l][r][k];
}
int main()
{
scanf("%lld" ,&n);
for(int i = 1;i <= n; i++){
scanf("%lld" ,&co[i]);
}
for(int i = 1;i <= n; i++){
scanf("%lld" ,&len[i]);
}
memset(dp,-1,sizeof(dp));
dfs(1,n,0);
printf("%lld" ,dp[1][n][0]);
return 0;
}
标签:dfs,return,方块,题解,len,消除,long,dp 来源: https://www.cnblogs.com/Crazyman-W/p/14766036.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。