「日常训练」Jongmah(Codeforces-1110D)
题意
你有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;
}
「日常训练」Jongmah(Codeforces-1110D)的更多相关文章
- 「日常训练」ZgukistringZ(Codeforces Round #307 Div. 2 B)
题意与分析(CodeForces 551B) 这他妈哪里是日常训练,这是日常弟中弟. 题意是这样的,给出一个字符串A,再给出两个字符串B,C,求A中任意量字符交换后(不限制次数)能够得到的使B,C作为 ...
- 「日常训练」Watering Flowers(Codeforces Round #340 Div.2 C)
题意与分析 (CodeForces 617C) 题意是这样的:一个花圃中有若干花和两个喷泉,你可以调节水的压力使得两个喷泉各自分别以\(r_1\)和\(r_2\)为最远距离向外喷水.你需要调整\(r_ ...
- 「日常训练」Alternative Thinking(Codeforces Round #334 Div.2 C)
题意与分析 (CodeForces - 603A) 这题真的做的我头疼的不得了,各种构造样例去分析性质... 题意是这样的:给出01字符串.可以在这个字符串中选择一个起点和一个终点使得这个连续区间内所 ...
- 「日常训练」More Cowbell(Codeforces Round #334 Div.2 B)
题意与分析(CodeForces 604B) 题意是这样的:\(n\)个数字,\(k\)个盒子,把\(n\)个数放入\(k\)个盒子中,每个盒子最多只能放两个数字,问盒子容量的最小值是多少(水题) 不 ...
- 「日常训练」Duff in the Army (Codeforces Round #326 Div.2 E)
题意(CodeForces 588E) 给定一棵\(n\)个点的树,给定\(m\)个人(\(m\le n\))在哪个点上的信息,每个点可以有任意个人:然后给\(q\)个询问,每次问\(u\)到\(v\ ...
- 「日常训练」Kefa and Dishes(Codeforces Round #321 Div. 2 D)
题意与分析(CodeForces 580D) 一个人有\(n\)道菜,然后要点\(m\)道菜,每道菜有一个美味程度:然后给你了很多个关系,表示如果\(x\)刚好在\(y\)前面做的话,他的美味程度就会 ...
- 「日常训练」Kefa and Park(Codeforces Round #321 Div. 2 C)
题意与分析(CodeForces 580C) 给你一棵树,然后每个叶子节点会有一家餐馆:你讨厌猫(waht?怎么会有人讨厌猫),就不会走有连续超过m个节点有猫的路.然后问你最多去几家饭店. 这题我写的 ...
- 「日常训练」Kefa and Company(Codeforces Round #321 Div. 2 B)
题意与分析(CodeForces 580B) \(n\)个人,告诉你\(n\)个人的工资,每个人还有一个权值.现在从这n个人中选出m个人,使得他们的权值之和最大,但是对于选中的人而言,其他被选中的人的 ...
- 「日常训练」Case of Matryoshkas(Codeforces Round #310 Div. 2 C)
题意与分析(CodeForces 556C) 为了将所有\(n\)个娃娃编号递增地串在一起(原先是若干个串,每个串是递增的), 我们有两种操作: 拆出当前串中最大编号的娃娃(且一定是最右边的娃娃). ...
随机推荐
- Kali-linux使用Aircrack-ng工具破解无线网络
Aircrack-ng是一款基于破解无线802.11协议的WEP及WPA-PSK加密的工具.该工具主要用了两种攻击方式进行WEP破解.一种是FMS攻击,该攻击方式是以发现该WEP漏洞的研究人员名字(S ...
- PHP+JQUERY+AJAX上传、裁剪图片
PHP部分 /*图片上传*/ public function upload1(){ $file = $_FILES['file']; $upload = new \Think\Upload();// ...
- mark DOwm
https://github.com/summerscar/live2dDemo {% cq %} 人生乃是一面镜子, 从镜子里认识自己, 我要称之为头等大事, 也只是我们追求的目的! {% endc ...
- PyTorch Softmax
PyTorch provides 2 kinds of Softmax class. The one is applying softmax along a certain dimension. Th ...
- 关于selenium获取token sessionid
# 获取sessionid def get_sessionid(self): # 是要从localStorage中获取还是要从sessionStorage中获取,具体看目标系统存到哪个中 # wind ...
- PAT——1069. 微博转发抽奖
小明PAT考了满分,高兴之余决定发起微博转发抽奖活动,从转发的网友中按顺序每隔N个人就发出一个红包.请你编写程序帮助他确定中奖名单. 输入格式: 输入第一行给出三个正整数M(<= 1000).N ...
- [LuoguP1352][FJSC]没有上司的舞会
[LuoguP1352][FJSC]没有上司的舞会(Link) 现在你有一棵树,每一个点有一个点权\(R[i]\),如果选择了\(i\)点,那么\(i\)子树上的所有的点都不能选,现在要求选择若干个点 ...
- tomcat启动错误org.springframework.beans.factory.CannotLoadBeanClassException的解决
tomcat启动时一直报这个错误,但是报错的类确实存在. 清空tomcat,更新maven项目,重配tomcat都没有解决. 最后解决办法: Eclipse环境:Project-->clean ...
- 【Javascript-基础-Date】本地时间与UTC(GMT)时间转换
UTC(GMT) 整个地球分为二十四时区,每个时区都有自己的本地时间.在国际无线电通信场合,为了统一起见,使用一个统一的时间,称为通用协调时(UTC, Universal Time Coordinat ...
- C++程序设计入门(上) 函数学习
局部变量和全局变量的访问: 全局变量的作用域时全局,局部变量的作用域是局部,若全局和局部的变量名相同的话,局部变量的改变不会引起全局变量的改变#include<iostream> int ...