CF Codeforces Global Round 1 D. Jongmah /*dp*/

本文深入探讨了CFCodeforcesGlobalRound1D.Jongmah中的三元对DP问题,通过减少状态空间来简化复杂度,利用数字重复特性优化算法。文章详细介绍了如何在考虑边界条件下,使用三维DP数组实现高效求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 CF Codeforces Global Round 1 D. Jongmah /*三元对dp*/

 

dp,有难度。。。

发现,如果同样的数字很多,一定先取那些一样的配对,所以先计算出每个数有几个,所以可以减少dp的范围。

因为3个[i,i+1,i+2]可以转换为[i,i,i],[i+1,i+1,i+1],[i+2,i+2,i+2]。dp的时候对于一个三元对[i,i+1,i+2]只需要转移他是0个,1个,2个的情况这样就可以减少dp范围。

因为对于一个大小为i的数,包含他的三元有序对为[i-2,i-1,i],[i-1,i,i+],[i,i+1,i+2],大小为i-1的数,包含他的三元有序对为[i-3,i-2,i-1],[i-2,i-1,i],[i-1,i,i+1]。发现两项的有两个三元有序对重合,就可以记录,有了上述的范围,就可以dp了。

然后中途加上去掉选取连号之后剩下的相同号的情况。

注意边界:选取对数,不能超过个数。不注意这个,中途可能会出错。

/*
	Date: 10/02/19 16:44
	Description: 
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;	
int dp[1000005][3][3];
int a[1000005];/*每个数出现的次数*/ 
int main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		int a_i;
		scanf("%d",&a_i);
		a[a_i]++;
	}
	for(int i=1;i<=m;i++){
		for(int j=0;j<=2;j++){
			for(int k=0;k<=2;k++){
				for(int z=0;z<=2;z++){
					if(z+k+j>a[i]) continue;/*边界处理,很简洁*/ 
					dp[i][j][k]=max(dp[i][j][k],
					  dp[i-1][z][j]+k+(a[i]-j-k-z)/3);
					/*cout<<"dp"<<i<<"|"<<j<<"|"<<k<<' '<<dp[i][j][k]<<endl;*/
				}	
			}
		}
	}
	cout<<dp[m][0][0];
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值