题意

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

分析

根据官方Editorial的说法,似乎没有一个真正正确的贪心(但是说不定就有人乱搞出来了)。这里用dp来解决问题。

这种dp题目我没做过,这次涨姿势了。首先要搞明白一个事实:我们完全可以保证构建一个最优解,其中连续的三元组对于每个数不会出现超过两个——因为如果出现超过三个,就可以拆分成三个相同组。在这样的前提下,我们就可以构建状态了。

进一步思考状态怎么得到的。对于第i个数,与之的相关的顺子有\([i-2,i-1,i],[i-1,i,i+1],[i,i+1,i+2]\),而全考虑是不必要的,重复了。选择两种状态考虑转移即可,这里考虑\([i-1,i,i+1]\)和\([i,i+1,i+2]\)。

暴力枚举他们分别有几种可能的情况(前面说了只有0,1,2三种情况),然后考虑转移,它们如何从i移动到i+1为center?那得看有几个i+1:记\(dp[i][j][k]\)为前i个数有j个第一种顺子和k种第二个顺子,那么就会剩下\(cnt[i+1]-j-k\)个i+1。我们不去考虑后面的i+2,i+3到底存不存在(因为如果不存在,后面推导的时候将只会更新j=0,k=0的情况),直接思考这些i+1分别会产生多少种顺子——暴力枚举产生0,1,2种连顺子(\([i+1,i+2,i+3]\))即可。这样就能写出具体的状态转移方程了。具体见代码。

这样一来,这题就能得到解决。如果内存要求苛刻,可以使用滚动数组解决(提示:计算结果用到的结果并不多)。

代码

#include <bits/stdc++.h>

#define INF 0x3f3f3f3f
#define PB emplace_back
#define MP make_pair
#define fi first
#define se second
#define rep(i,a,b) for(repType i=(a); i<=(b); ++i)
#define per(i,a,b) for(repType i=(a); i>=(b); --i)
#define ZERO(x) memset(x, 0, sizeof(x))
#define MS(x,y) memset(x, y, sizeof(x))
#define ALL(x) (x).begin(), (x).end() #define QUICKIO \
ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0);
#define DEBUG(...) fprintf(stderr, __VA_ARGS__), fflush(stderr) using namespace std;
using pi=pair<int,int>;
using repType=int;
using ll=long long;
using ld=long double;
using ull=unsigned long long; const int MAXN = 100005;
int cnt[MAXN], dp[MAXN][3][3]; int main()
{
int n,m; cin>>n>>m;
ZERO(cnt);
rep(i,1,n)
{
int tmp; cin>>tmp;
cnt[tmp]++;
}
MS(dp, -1);
dp[0][0][0]=0; rep(i,0,m+1)
{
rep(j,0,2)
{
rep(k,0,2)
{
if(dp[i][j][k]<0) continue;
int now=cnt[i+1]-j-k;
for(int t=0; t<=2 && t<=now; ++t)
{
dp[i+1][k][t] = max(dp[i+1][k][t], dp[i][j][k]+(now-t)/3+t);
}
}
}
}
cout<<dp[m+1][0][0]<<endl;
return 0;
}

最新文章

  1. Java反编译代码对齐
  2. 10——operator=返回reference to *this
  3. 关于Socket编写简单聊天工具的总结(原创)
  4. gei shilei d
  5. 专题二、ArrayList序列化技术细节详解
  6. 关于一个简单面试题(。net)
  7. 怎样制作一个相似Tiny Wings的游戏 Cocos2d-x 2.1.4
  8. Yii中CDbCriteria常用总结
  9. bzoj3209 花神的数论题 (二进制数位dp)
  10. c语言字符相关函数
  11. MUI体验框架
  12. SpringCloud的服务注册中心(三) - 进一步了解 Eureka
  13. django日志,django-crontab,django邮件模块
  14. Vue 限制input输入 限数字 或 小数点后两位number
  15. Codeforces gym102152 K.Subarrays OR
  16. JEECG新版UI规划,主要提供H5方案(采用主流技术)
  17. 高效开发iOS系列 -- 那些不为人知的KVC
  18. javascript Set data structures
  19. angular学习笔记(二十六)-$http(4)-设置请求超时
  20. .net手动编写Windows服务

热门文章

  1. Kali-linux破解LM Hashes密码
  2. [Python 网络编程] makefile (三)
  3. nginx 反向代理 proxy_pass 及对比nginx与haproxy反向代理服务器功能、性能的优劣
  4. rsync + mysql + gzip + --single-transaction
  5. 关于Oracle 数据库死锁 转
  6. C#设计模式 —— 工厂模式
  7. Vue 源码分析—— 目录结构
  8. select 宽度跟随option内容自适应
  9. $.ajax 完整参数
  10. 偏前端--之小白学习本地存储与cookie