【CF global1 D / CF1110D】 Jongmah

题意

你有n个数字,范围[1, m],你可以选择其中的三个数字构成一个三元组,但是这三个数字必须是连续的或者相同的,每个数字只能用一次,问这n个数字最多构成多少个三元组?

分析

这里想谈一下DP的一个套路,捆绑
有的DP题目,它可能会要求和一些东西捆绑,求方案数,这种时候如何单点设置状态呢?
以这个题为例,只考虑前i种数字,对于数字i,它可能 (i,i,i) (i-2,i-1,i) (i-1,i) (i,) 如果是后两种,它还未构成一个合法的序列,我们还不知道是否存在i+1来完善它
也就是考虑前i种数字的时候,后两种不应该被计入方案数里,但转移的时候我们要用到他们的数量,这里就可以再用两维将他的数量捆绑起来一起转移
状态
dp[i][j][k] 表示只考虑前i种数字,捆绑了j个(i-1,i) k个(i)的最大方案数
初始条件
dp[0][0][0] = 0 ,others = -inf
因为假设只考虑前0种数字(实际不存在,假定数量为0),它无法构成任何三元组,但是转移到前1种可以用前0种转移过来
其余的都是未求解状态 ,默认为负无穷
转移方案
我们有a[i+1]个i+1
考虑如何从dp[i][j][k]转移到前i+1个去
考虑第一个贪心策略:如果有未完成的三元组,优先补全它,因为如果不补全,它便会向后需求,这样无论如何也不会让答案更大
所以我们需要用j+k个i+1 去补全(i-1,i)和(i)这样我们形成了j个(i-1,i,i+1)可以计入方案数里,以及k个(i,i+1)
还剩下a[i+1] - j - k个i+1
枚举我们捆绑多少个(i+1),将剩下的全部变成(i+1,i+1,i+1)
这样转移的方程就确定了
dp[i+1][k][t] = max ( dp[i+1][k][t] , dp[i][j][k] + j + (a[i+1]-j-k-t)/3)
最终答案就是只考虑前m个数字,最大的答案

代码

#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[1000005];
int dp[1000005][3][3];
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int tmp;
    cin>>n>>m;
    for(int i=1;i<=n;i++) {
    cin>>tmp;
    a[tmp]++;
    }
    memset(dp,0x80,sizeof(dp));
    dp[0][0][0] = 0;
    for(int i=0;i<m;i++) {
    for(int j=0;j<3;j++) {
        for(int k=0;k<3;k++) {
        int res = a[i+1] -j - k;
        for(int t=0;t<3&&t<=res;t++) {
            dp[i+1][k][t] = max(dp[i+1][k][t],dp[i][j][k]+j+(res-t)/3);
        }
        }
    }
    }
    int ans =0 ;
    for(int i=0;i<3;i++) for(int j=0;j<3;j++) ans = max(ans,dp[m][i][j]);
    cout<<ans<<endl;

}

原文地址:https://www.cnblogs.com/greenty1208/p/10357533.html

时间: 2024-11-06 22:48:18

【CF global1 D / CF1110D】 Jongmah的相关文章

【CF 549G Happy Line】排序

题目链接:http://codeforces.com/problemset/problem/549/G 题意:给定一个n个元素的整数序列a[], 任意时刻对于任一对相邻元素a[i-1]. a[i],若a[i-1] < a[i] 则要依次执行如下两个操作: 1. a[i-1]--, a[i]++: 2. 交换a[i-1]和a[i]的位置. 经过若干次1.2操作后,若能使整个序列变成非降的,则输出最终的序列:否则输出":(". 数据范围:n 属于 [1, 2*10^5], a[i]

【cf contest 1119 G】Get Ready for the Battle

题目 你有\(n\)个士兵,需要将他们分成\(m\)组,每组可以为0: 现在这些士兵要去攻打\(m\)个敌人,每个敌人的生命值为\(hp_i\) : 一轮游戏中一组士兵选定一个攻打的敌人,敌人生命值-=这组的人数: 胜利的判定是所有敌人的生命值为非正的: 输出胜利的最小轮数,可以达到最小轮数的分配方式,并输出每轮的策略: \(1 \le m \le n \le 10^6 \ , \ 1 \le \sum hp_i \le 10^6\) ; 题解 答案的下界是\(\lceil \frac{\sum

【CF 520D】Cubes

[CF 520D]Cubes 怎么说呢--英语阅读题+超级大模拟-- 最重要的是知道怎么出来的数据...题意好懂 xy坐标内给出几个单位正方形 以正方形左下点坐标给出 y=0为地面 正方形下面或者左右下方至少存在一个正方形他才能稳定.. 正方形按0~m-1标号 每次只能取出不影响整体结构的正方形 甲乙玩一个游戏 交替取正方形 每取下一个按从左到右的顺序排好 得到一个大数 重点来了! 取出的数是m进制 转换为十进制是最终结果 甲希望结果最大 乙希望结果最小 问结果为多少 甲先取 题意明白了模拟就行

【机器学习算法-python实现】协同过滤(cf)的三种方法实现

(转载请注明出处:http://blog.csdn.net/buptgshengod) 1.背景 协同过滤(collaborative filtering)是推荐系统常用的一种方法.cf的主要思想就是找出物品相似度高的归为一类进行推荐.cf又分为icf和ucf.icf指的是item collaborative filtering,是将商品进行分析推荐.同理ucf的u指的是user,他是找出知趣相似的人,进行推荐.通常来讲icf的准确率可能会高一些,通过这次参加天猫大数据比赛,我觉得只有在数据量非

【线段树】【树状数组】【CF 121E】幸运数列

1922. [CF 121E]幸运数列 ★★★ 输入文件:cf121e.in 输出文件:cf121e.out 简单对比 时间限制:3 s 内存限制:256 MB [题目描述] 对于欧洲人来说,"幸运数"是指那些十进制只由4或7组成的数.财务员Petya需要维护一个支持如下操作的整数数列: add l r d - 表示将[l, r]区间内的所有数加上一个正整数d(). count l r - 统计[l, r]区间内有多少个"幸运数".() 请你帮助Petya实现它.

【CF 474E】Pillars

[CF 474E]Pillars 离散化+线段树dp 大半夜写出来了...好长好长好长好长好挫--先把高度排序离散化 我又开了个哈希数组用来查某点对应离散后的点 然后遍历每个点时二分出满足题意的区间(1~h-d)(h+d~max) 然后线段树查两个区间当前最大长度的序列 累计到当前点对应的树内点 同时更新他的父亲点们的最大长度 再把之前最大长度的末尾作为当前点的前驱 如果没有就用当前点自己做前驱 最后输出树根存的节点的前驱们(即为树内最长的序列) 各种节点哈希的有点混乱--代码--看乱了就别看了

【CF 460C】Present

[CF 460C]Present 二分+贪心 二分最矮高度的最大值 每二分一个遍历看是否可达 可达low = mid+1不可达high = mid-1 可达的判断用贪心即可 改点长度不足时 在改点设置浇水点 同是在i+w设置断水 之后每个点都继承前一个点的浇水量 到i+w时减少i处浇的水即可 代码如下: #include <iostream> #include <cstdio> #include <cstring> #define sz 100000 #define l

【CF 459D】 Pashmak and Parmida&#39;s problem

[CF 459D] Pashmak and Parmida's problem 预处理+线段树求逆序对 新学了树状数组 很适合这题 来一发 代码如下: #include <iostream> #include <cstdio> #include <cstdlib> #include <map> #include <cstring> #define ll long long using namespace std; map <int,int&

【CF 515D】 Drazil and Tiles

[CF 515D] Drazil and Tiles 拓扑的思想 如果满足条件 '.'未遍历完之前肯定存在度为1的点(上下左右仅有一个'.') 遍历到一个1度点u时 将与他连的点v用对应括号括起 此时v也已匹配 入度归零 同时将与v相连的其余点入度减1 不断遍历知道遍历完所有'.' 若能遍历完 则满足条件否则无解或多解 (吐槽一下 原本用的纯粹拓扑思路 想想也是绝对要T的..后来改换BFS 代码如下: #include <iostream> #include <cstdio> #i