列表

详情


NC207438. 电竞胡司令

描述

大司马绰号“电竞胡司令”,因为他象棋下得很好。当然其他游戏也不在话下,其中也包括埃及祖玛。
埃及祖玛是一款风靡全球的游戏,其规则概括如下:
有一排珠子,从左至右编号为,每颗珠子有一个颜色,初始时,不存在三颗相邻的同色珠子。
你可以进行若干次操作,每次可以在序列的任意位置插入一颗任意颜色的珠子,插入完成后将进行检测。
如果此时有三颗及以上相邻珠子同色,那么这些珠子都将消失(如果最多有k个相邻的同色珠子那么k个全部消失,如果你没有玩过埃及祖玛,觉得此处表意模糊,你可以在备注中找到形式化的表述,备注中还有其他可能有用的信息),左右两边的序列合并为新序列,重复此过程直到不存在两颗相邻的同色珠子。
如果序列为空,则游戏结束。否则进行下一次插入。
现在,对于给定的序列,求出最少插入几次即可把序列删除为空。

输入描述

每个测试点仅包含一组输入数据。
第一行一个整数,表示初始的序列长度。
接下来一行n个非负整数,第i个整数表示左起第i个珠子的颜色。
保证不存在三颗相邻的同色珠子。

输出描述

输出一行一个整数,表示最少的插入次数。

示例1

输入:

6
1 1 4 5 1 4

输出:

6

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 2027ms, 内存消耗: 8292K, 提交时间: 2020-05-30 13:43:07

#include<bits/stdc++.h>
using namespace std;
const int N=1002;
int n,a[N],f[N][N],g[N][N];
int main(){
	scanf("%d",&n);
	memset(f,0x1f,sizeof(f));
	memset(g,0x1f,sizeof(g));
	f[1][0]=0;
	for(int i=1;i<=n;++i){
		scanf("%d",a+i);
		f[i][i]=2,f[i+1][i]=0;
	}
	for(int i=1;i<n;++i)
		f[i][i+1]=1+(a[i]!=a[i+1])*3;
	for(int i=3;i<=n;++i)
		for(int j=n-i+1;j;--j){
			int l=j,r=j+i-1,&u=f[l][r],&v=g[l][r];
			for(int k=l;k<r;++k)
				if(a[k]!=a[k+1]) u=min(u,f[l][k]+f[k+1][r]);
			for(int k=l+1;k<r;++k)
				if(a[k-1]!=a[k]&&a[k+1]!=a[k]&&a[k]==a[l-1]) v=min(v,f[l][k-1]+f[k+1][r]);
			if(a[l]!=a[r]) continue;
			if(a[l]!=a[l+1]&&a[r]!=a[r-1]) u=min(u,f[l+1][r-1]+1);
			if(a[l]==a[l+1]&&a[r]!=a[r-1]) u=min(u,f[l+2][r-1]);
			if(a[l]!=a[l+1]&&a[r]==a[r-1]) u=min(u,f[l+1][r-2]);
			if(a[l]!=a[l+1]&&a[r]!=a[r-1])
				for(int k=l+2;k<r-1;++k)
					if(a[l]==a[k]&&a[k]!=a[k-1]&&a[k]!=a[k+1])
						u=min(u,f[l+1][k-1]+f[k+1][r-1]);
			if(i==3) continue;
			if(a[l]==a[l+1]&&a[r]==a[r-1]) u=min(u,f[l+2][r-2]);
			if(a[l]==a[l+1]&&a[r]!=a[r-1])
				for(int k=l+2;k<r-1;++k)
					if(a[l]==a[k]&&a[k]!=a[k-1]&&a[k]!=a[k+1])
						u=min(u,f[l+2][k-1]+f[k+1][r-1]);
			if(a[l]!=a[l+1]&&a[r]==a[r-1])
				for(int k=l+2;k<r-1;++k)
					if(a[l]==a[k]&&a[k]!=a[k-1]&&a[k]!=a[k+1])
						u=min(u,f[l+1][k-1]+f[k+1][r-2]);
			if(a[l]!=a[l+1]&&a[r]!=a[r-1])
				for(int p=l+2;p<r-1;++p){
					if(a[p]==a[l]&&a[p]==a[p+1]) u=min(u,f[l+1][p-1]+f[p+2][r-1]);
					if(a[p]==a[l]&&a[p-1]!=a[p]&&a[p+1]!=a[p])
						u=min(u,f[l+1][p-1]+g[p+1][r-1]);
				}
		}
	printf("%d",f[1][n]);
	return 0;
}

上一题