原文链接https://www.cnblogs.com/zhouzhendong/p/CF1110D.html

题意

  给定 n 个数,每一个数都是在 [1,m] 里的整数。

  从中取出形如 {x,x,x} 或者 {x-1,x,x+1} 的集合,各个集合不能相交,问最多能取出几个。

  $n,m\leq 10^6$

题解

  标算非常简洁。

  我这里讲讲我的做法,尽管相对复杂。

  首先,我们可以忽略对于同一个 x ,取出大于2次 {x-1,x,x+1} 这种情况,因为这种可以用取 {x-1,x-1,x-1} {x,x,x} {x+1,x+1,x+1} 来代替。

  所以一个x 最多被形如 {a-1,a,a+1} 的pair 取 6 次。即 {x-2,x-1,x}*2   , {x-1,x,x+1}*2 ,  {x,x+1,x+2}*2  。

  现在来证明一个重要结论:

  如果 x 的个数大于 7 ,那么至少可以取出一次 {x,x,x} 。(也就是说我们可以先不断取 {x,x,x} 这种pair,直到所有数字的出现次数都小于等于7)

  设 t[x] 表示 x 的出现次数。

  对于 t[x] = 8 的情况,考虑到它最多被形如 {a-1,a,a+1} 的这种pair取到6次,所以如果不取 {x,x,x} ,至少会多出2个。如果取了 {x,x,x} ,那么最多会影响一个形如 {a-1,a,a+1} 的pair,导致另外两个数不能取了,但是如果不取 {x,x,x} 也会多出两个,所以至少不亏。

  对于 t[x]>8 的情况就更加显然了。

  于是现在 t[x] < 8 。 考虑 dp ,设 dp[i][j][k] 表示  [1,i] 中,i 被取了 j 次, i + 1 被取了 k 次,且 [1,i-1] 的数被取的次数没有超限,  [i+2,m] 的数没有被取过, 这种情况下取出的pair的最大个数。直接枚举转移暴力dp就好了。

  时间复杂度 O(n) *  大常数。

  实测可过。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL read(){
LL x=0,f=0;
char ch=getchar();
while (!isdigit(ch))
f|=ch=='-',ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?-x:x;
}
const int N=1000005;
int n,m;
int t[N],ans=0;
int dp[N][8][8];
void ckmax(int &x,int y){
x=x>y?x:y;
}
int main(){
n=read(),m=read();
for (int i=1;i<=n;i++)
t[read()]++;
for (int i=1;i<=m;i++)
while (t[i]>7)
t[i]-=3,ans++;
for (int i=0;i<=m;i++)
for (int a=0;a<=7;a++)
for (int b=0;b<=7;b++)
dp[i][a][b]=-N*2;
dp[0][0][0]=0;
for (int i=0;i<m;i++)
for (int a=0;a<=7;a++)
for (int b=0;b<=7;b++){
if (dp[i][a][b]<-N||a>t[i]||b>t[i+1])
continue;
int v=dp[i][a][b];
for (int x=0;x<=2;x++)
for (int y=0;y<=2;y++)
if (a+x*3+y<=t[i]&&b+y<=t[i+1])
ckmax(dp[i+1][b+y][y],v+x+y);
}
int k=0;
for (int i=0;i<=t[m];i++)
ckmax(k,dp[m][i][0]+(t[m]-i)/3);
cout<<ans+k;
return 0;
}

  

Codeforces 1110D. Jongmah 动态规划的更多相关文章

  1. Codeforces 1110D Jongmah [DP]

    洛谷 Codeforces 我-我我把这-这这题切了??? 说实话这题的确不难,只是我看到有大佬没做出来有点慌-- 突然发现这题是我在洛谷的第500个AC呢.那就更要写篇题解纪念一下了. 思路 容易想 ...

  2. Codeforces 1110D Jongmah (DP)

    题意:你有n个数字,范围[1, m],你可以选择其中的三个数字构成一个三元组,但是这三个数字必须是连续的或者相同的,每个数字只能用一次,问这n个数字最多构成多少个三元组? 解析:首先我们容易发现,我们 ...

  3. 【Codeforces 1110D】Jongmah

    Codeforces 1110 D 题意:给\(n\)个麻将,每个麻将上有一个\(1..m\)的整数\(a_i\). 现在要将这些麻将们分成一个一个三元组,有两种情况: \([i-1,i,i+1]\) ...

  4. 【Codeforces 1110D】Jongmah FST分析

    Codeforces 1110 D FST分析 dotorya.FizzyDavid.MofK.gamegame.matthew99.chokudai.eddy1021.DBradac.Happy_N ...

  5. Jongmah CodeForces - 1110D

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

  6. Codeforces Flipping game 动态规划基础

    题目链接:http://codeforces.com/problemset/problem/327/A 这道题目有O(N^3)的做法,这里转化为动态规划求解,复杂度是O(N) #include < ...

  7. Codeforces 955F Heaps - 动态规划

    题目传送门 传送点I 传送点II 传送点III 题目大意 给定一棵以1为根的树,定义$dp_{k}(u)$表示在$u$的子树内存在的深度最大的满k叉树的深度,求$\sum_{u = 1}^{n}\su ...

  8. Codeforces Gym 101623A - 动态规划

    题目传送门 传送门 题目大意 给定一个长度为$n$的序列,要求划分成最少的段数,然后将这些段排序使得新序列单调不减. 考虑将相邻的相等的数缩成一个数. 假设没有分成了$n$段,考虑最少能够减少多少划分 ...

  9. [线性DP][codeforces-1110D.Jongmah]一道花里胡哨的DP题

    题目来源: Codeforces - 1110D 题意:你有n张牌(1,2,3,...,m)你要尽可能多的打出[x,x+1,x+2] 或者[x,x,x]的牌型,问最多能打出多少种牌 思路: 1.三组[ ...

随机推荐

  1. 基于scrapy-redis的分布式爬虫

    一.介绍 1.原生的scrapy框架 原生的scrapy框架是实现不了分布式的,其原因有: 1. 因为多台机器上部署的scrapy会各自拥有各自的调度器,这样就使得多台机器无法分配start_urls ...

  2. 【并发编程】【JDK源码】JDK的(J.U.C)java.util.concurrent包结构

    本文从JDK源码包中截取出concurrent包的所有类,对该包整体结构进行一个概述. 在JDK1.5之前,Java中要进行并发编程时,通常需要由程序员独立完成代码实现.当然也有一些开源的框架提供了这 ...

  3. python之模块之shutil模块

    shutil -- --High-level file operations  高级的文件操作模块. os模块提供了对目录或者文件的新建/删除/查看文件属性,还提供了对文件以及目录的路径操作.比如说: ...

  4. MySQL安全配置向导mysql_secure_installation详解

    安装完mysql-server 会提示可以运行mysql_secure_installation.运行mysql_secure_installation会执行几个设置:  a)为root用户设置密码  ...

  5. MySQL学习笔记(六)MySQL8.0 配置笔记

    今天把数据库配置文件修改了,结果重启不了了 需要使用 mysqld --initialize 或 mysqld --initialize-insecure 命令来初始化数据库 1.mysqld --i ...

  6. MongoDB3.6 一键化自动部署方案

    1.系统基础配置 下面的命令默认都使用root用户进行操作,操作系统为Centos7,mongodb3.6.x以上版本 1.1 修改系统配置文件/etc/security/limits.conf和/e ...

  7. JavaScript 基本类型和引用类型

    前言 ECMAScript变量可能包含两种不同数据类型的值:基本类型值和引用类型值.基本类型值指的是简单的数据段,而引用类型值指那些可能由多个值构成的对象. 基本类型 Undefined.Null.B ...

  8. Nginx虚拟主机 子文件单独配置

    上一篇所有的server 全都配置在nginx.conf配置文件里,其实每个server 都可以单独做一个子文件 删除nginx.conf配置文件中的server及其余内容,加上如下图 创建保存每个虚 ...

  9. MyEclipse编码方式设置

    1.windows -> Preferences -> general -> Workspace:

  10. webpack构建Vue工程

    先开始webpack基本构建   创建一个工程目录 vue-structure mkdir vue-structure && cd vue-structure   安装webpack ...