P2135块消除。
目录标题描述输入格式输出格式输入输出样本思路代码P2135块消除。
题目
https://www.luogu.com.cn/problem/UVA10559
https://www.luogu.com.cn/problem/P2135
题目描述
吉米最近迷上了一种叫做方块淘汰的游戏。游戏规则如下:N个彩色方块排成一排,相同颜色的方块连接成一个区域(如果相邻的两个方块颜色相同,那么这两个方块属于同一个区域)。为了简化主题,用一个数字来表示连接在一起的相同颜色的正方形的数量。
例如,9 122233331表示为。
4 1 2 3 1
1 3 4 1
玩游戏时,可以选择要擦除的区域。如果这个区域包含的方块数是x,你会得到x 2的分数。方块被擦除后,剩余的方块将垂直落到底部或其他方块上。而当一排方块被完全抹掉后,它右边的所有方块都会向左移动一个方块。我希望吉米能找到获得最高分的最佳方案。你能帮助他吗?
输入格式
第一行包含整数m(1=m=50),表示相同颜色的块数。第二行包含m的数字,表示每个方块的颜色(1到m之间的整数)。
输出格式
只有一个整数,可能的最高分。
输入输出样例
输入 #1
四
1 2 3 1
1 3 4 1
输出 #1
29
思路
让\(f_{i,j,k}\)表示消除\(l,r\)之间的方块,与\(i\)颜色相同的方块保留\(k\)的最大分数。
关于初始化,很明显有:个\ (f _ {I,I,0 }=num _ I ^ 2,f _ {I,I,num _ I}=0 \),其中\(num_i\)是第\(i\)个区域的方块数。
转移有点复杂,要看代码,核心是枚举保留还是消去。
代码
#包含iostream
#包含cstdio
#包含cstring
#定义整数长
使用命名空间标准;
int read(){ 0
int re=0;
char c=getchar();
bool negt=false
while(c '0' || c '9 ')
negt |=(c=='-'),c=getchar();
while(c='0' c='9 ')
re=(re 1) (re 3) c - '0 ',c=getchar();
返回negt-re : re;
}
const int N=210
int col[N];//颜色
整数;
int f[55][55][1010];
int n;
int solve(){ 0
memset(col,0,sizeof(col));
memset(num,0,sizeof(num));
memset(f,0,sizeof(f));
n=read();
int sum=0;
for(int I=1;I=n;I)col[I]=read();
for(int I=1;I=n;i )num[i]=read(),sum=num[I];
memset(f,-0x3f,sizeof(f));
for(int I=1;I=n;(一)
f[i][i][0]=num[i] * num[i],f[I][I][num[I]]=0;
for(int I=n;I 0;i -)
for(int j=I ^ 1;j=n;j ) {
for(int k=I;k j;k){ 0
f[i][j][0]=max(f[i][j][0],f[I][k][0]f[k 1][j][0]);
if(col[i]==col[k 1])
for(int l=0;l=总和;L) {//枚举[k ^ 1,j]并将l框留为与col[i]相同的颜色。
f[i][j][l]=max(f[i][j][l],f[I][k][0]f[k 1][j][l]);
if(I 1=k){ 0
f[i][j][0]=最大值(
f[i][j][0],
f[i 1][k][0] f[k 1][j][l] (l数[i]) * (l数[i])
) ;
f[i][j][l数量[i]]=最大值(
f[i][j][l数量[i]],
f[i 1][k][0] f[k 1][j][l]
);
}
}
}
}
返回f[1][n][0];
}
签名main(){ 0
printf('%lld ',solve());
返回0;
}
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/52097.html