Codeforces Global Round 1 D - Jongmah

本文解析了CodeForces竞赛中一道关于组合三元组的难题。通过动态规划方法,详细阐述了如何最大化由给定整数组合的三元组数量,重点关注相同数值和连续数值的三元组形成策略。

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

  • 题目链接:http://codeforces.com/contest/1110/problem/D
  • 题意:给你两个整数n、m,表示:给你n个整数,每个整数的范围都在[1 , m]。现在可以将三个数值相同的数(如:777)或者三个数值连续的数(如:123,但112不算)组成一个三元组,问这n个数最多能组多少个三元组?(每个数最多只能用在一个三元组中)
  • 因为3个连续三元组可以转换成三个相同数值的三元组,所以对于一种连续三元组,其个数最多有2个。那么对于一个数值等于 i的数(可能有多个数的数值等于i),其除了组成相同数的三元组以外,组成了x个[i-2, i-1, i],y个[i-1, i, i+1], z个[i, i+1, i+2] (0<= x,y,z <=2),这是对于数值i的所有情况,也就是对于数值i的所有可能的状态。那么设dp[i][y][z]表示在组成y个[i-1, i, i+1], z个[i, i+1, i+2] 的状态下,在只使用小于等于数值i的数时(1<= i <= m)(也就是dp[i][y][z]的值并没有算上这 y+z 个三元组),最多组成了多少个三元组
  • 注意点:要把dp初始化为 负无穷,表示此种情况不存在。令dp[0][0][0] = 0,表示此种情况存在,但数量为0。
#include <bits/stdc++.h>
#define pi acos(-1.0 )
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;//4e18 ~= 2^62
const int maxn =1e6 + 10;
const LL mod = 1e9+7;

int a[maxn], dp[maxn][3][3];

int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    int tmp;
    for(int i=1; i<=n; i++){
        scanf("%d", &tmp);
        a[tmp]++;
    }
    memset(dp, -INF, sizeof(dp));
    dp[0][0][0] = 0;
    for(int i=1; i<=m; i++){
        for(int x=0; x<3; x++){
            for(int y=0; y<3; y++){
                for(int z=0; z<3; z++){
                    if(a[i] < x+y+z) continue;
                    dp[i][y][z] = max(dp[i][y][z], dp[i-1][x][y] + (a[i]-x-y-z)/3 + x);
                }
            }
        }
    }
    printf("%d\n", dp[m][0][0]);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值