AT_joisc2015_i

先将暴力转移方程列出来:设 dpi,j,k,l 表示当前 A 牌堆最上面三张分别是第 i,j,k 张牌,B 牌堆最上面是第 l 张的最大价值。则有:

dpi,j,k,ldpj,k,k+1,i(ci=clai=al)

dpi,j,k,ldpi,j,k+1,k(ck=clak=al)

O(n4),明显不能过。考虑优化。发现状态数 O(n4),转移 O(1),优化状态即可。

容易发现,两种转移的目标装态的 k 都为 k+1。可以考虑优化这一维。同时发现,要么 k=j+1,要么 k=l+1。所以可以将状态变为 dpi,j,k,0/1 表示 A 牌堆最上面三张为第 i,j,j+1/l+1 张牌,B 牌堆最上面为第 k 张的最大值。一样转移即可。

对于处理最后 j,k 可能为 0>n 的情况,可以先塞两个全为 0 的物品到最后。

code:

点击查看代码
int n,m,a[N],b[N],c[N],dp[N][N][N][2];
void Yorushika(){
	scanf("%d",&n);
	rep(i,1,n){
		scanf("%d%d%d",&a[i],&b[i],&c[i]);
	}
	n++,a[n]=b[n]=c[n]=0;
	n++,a[n]=b[n]=c[n]=0;
	mems(dp,-0x3f);
	dp[2][3][1][0]=c[1];
	dp[1][2][3][1]=c[3];
	int ans=0;
	rep(i,1,n){
		rep(j,1,n){
			rep(l,1,n){
				if(dp[i][j][l][0]>-1e9){
					int k=j+1;
					if(a[i]==a[l]||b[i]==b[l]||!a[i])
						dp[j][k][i][0]=max(dp[j][k][i][0],dp[i][j][l][0]+c[i]);
					if(a[k]==a[l]||b[k]==b[l]||!a[k])
						dp[i][j][k][1]=max(dp[i][j][k][1],dp[i][j][l][0]+c[k]);
					ans=max(ans,dp[i][j][l][0]);
				}
				if(dp[i][j][l][1]>-1e9){
					int k=l+1;
					if(a[i]==a[l]||b[i]==b[l]||!a[i])
						dp[j][k][i][0]=max(dp[j][k][i][0],dp[i][j][l][1]+c[i]);
					if(a[k]==a[l]||b[k]==b[l]||!a[k])
						dp[i][j][k][1]=max(dp[i][j][k][1],dp[i][j][l][1]+c[k]);
					ans=max(ans,dp[i][j][l][1]);
				}
			}
		}
	}
	printf("%d\n",ans);
}
signed main(){
	int t=1;
	//	scanf("%d",&t);
	while(t--)
		Yorushika();
}
posted @   yinhee  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示