Codeforces 1110D Jongmah (DP)
题意:你有n个数字,范围[1, m],你可以选择其中的三个数字构成一个三元组,但是这三个数字必须是连续的或者相同的,每个数字只能用一次,问这n个数字最多构成多少个三元组?
解析:首先我们容易发现,我们发现,假设有3个三元组(x, x + 1, x + 2),我们不妨把这3个三元组换成(x, x, x), (x + 1, x + 1, x + 1), (x + 2, x + 2, x + 2)这3个三元组。那么,对于每个x,最多有2个(x, x + 1, x + 2)这样的三元组。这样,每个阶段的状态数就是有限的了。
设dp[i][j][k]为数字1到i,有j个(i - 1, i , i + 1)三元组,k个(i , i + 1, i + 2)三元组可以组成的最多的三元组的数目,我们现在考虑向i + 1转移。因为前面有j个(i - 1, i , i + 1),k个(i , i + 1, i + 2),假设本来有t个i + 1,那么现在可用来构成新的三元组的i + 1有t - j - k个。
这t - j - k个i + 1可以用来构成(i + 1, i + 2, i + 3),也可用来构成(i + 1, i + 1, i + 1)。我们就可以枚举这些i + 1是形成什么样的三元组来进行状态转移了。初态:dp[0][0][0] = 0,其余负无穷。末态:dp[m + 1][0][0]。因为m + 1肯定没有数,所以dp[m + 1][0][0]是m + 1处的唯一合法状态,也就是答案。
代码:
#include <bits/stdc++.h>
#define ls(x) (x << 1)
#define rs(x) ((x << 1) | 1)
#define lowbit(x) (x & (-x))
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1000010;
int a[maxn], cnt[maxn];
int dp[maxn][3][3];
int main () {
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
cnt[a[i]]++;
}
memset(dp, -0x3f, sizeof(dp));
dp[0][0][0] = 0;
for (int i = 0; i <= m + 1; i++) {
for (int j = 0; j < 3; j++)
for (int k = 0; k < 3; k++) {
if(dp[i][j][k] < 0) continue;
int now = cnt[i + 1] - j - k;
for (int t = 0; t < 3 && t <= now; t++) {
dp[i + 1][k][t] = max(dp[i + 1][k][t], dp[i][j][k] + (now - t) / 3 + t);
}
}
}
printf("%d\n", dp[m + 1][0][0]);
return 0;
}
Codeforces 1110D Jongmah (DP)的更多相关文章
- codeforces Educational Codeforces Round 16-E(DP)
题目链接:http://codeforces.com/contest/710/problem/E 题意:开始文本为空,可以选择话费时间x输入或删除一个字符,也可以选择复制并粘贴一串字符(即长度变为两倍 ...
- CF1110D Jongmah(DP)
题目链接:CF原网 洛谷 题目大意:有 $n$ 个数,每个都不超过 $m$.一个三元组 $(a,b,c)$ 是合法的当且仅当 $a=b=c$ 或者 $a+1=b=c-1$.每个数只能用一次.问最多能 ...
- Codeforces 837D--Round Subset (DP)
原题链接:http://codeforces.com/contest/837/problem/D 题意:在n个数字中,取k个数,使这些数的乘积后缀“0”的个数最大,输出后缀0的最大数量. 思路:显然只 ...
- CodeForces 455A Boredom (DP)
Boredom 题目链接: http://acm.hust.edu.cn/vjudge/contest/121334#problem/G Description Alex doesn't like b ...
- Codeforces 864E Fire(DP)
题目链接 Fire 题意 有n个物品,每个物品的挽救时间代价为ti, 消失时刻为di, 价值为pi. 如果要救某个物品,必须在他消失之前救出来. 同一时刻最多只能救一件物品. 当前耗时为当前已经救出的 ...
- LightOJ 1033 Generating Palindromes(dp)
LightOJ 1033 Generating Palindromes(dp) 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid= ...
- lightOJ 1047 Neighbor House (DP)
lightOJ 1047 Neighbor House (DP) 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87730# ...
- UVA11125 - Arrange Some Marbles(dp)
UVA11125 - Arrange Some Marbles(dp) option=com_onlinejudge&Itemid=8&category=24&page=sho ...
- 【POJ 3071】 Football(DP)
[POJ 3071] Football(DP) Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4350 Accepted ...
随机推荐
- 论文笔记 — Learning to Compare Image Patches via Convolutional Neural Networks
论文: 引入论文中的一句话来说明对比图像patches的重要性,“Comparing patches across images is probably one of the most fundame ...
- 八大排序算法原理以及Java实现(直接插入排序)
概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大, ...
- count(*) 和count(1) 有区别吗
create table test1 (a varchar2(2),b varchar2(2)); insert into test1 values ('b','c'); insert into te ...
- LeetCode OJ:Serialize and Deserialize Binary Tree(对树序列化以及解序列化)
Serialization is the process of converting a data structure or object into a sequence of bits so tha ...
- db2生成连续日期
//生成时间段内连续日期 select * from ( select date('2008-01-01') + (row_NUMBER() over () -1) days AS datennn f ...
- linux命令学习笔记(28):tar命令
通过SSH访问服务器,难免会要用到压缩,解压缩,打包,解包等,这时候tar命令就是是必不可少的一个功能强大的 工具.linux中最流行的tar是麻雀虽小,五脏俱全,功能强大. tar命令可以为linu ...
- eShopOnWeb
eShopOnWeb https://www.cnblogs.com/sheng-jie/p/9616675.html 构建现代Web应用 1.引言 eShopOnWeb是基于ASP.NET Core ...
- Mesos-slave启动处理记录
1. work_dir错误导致启动异常 /etc/mesos-slave/work_dir设置的目录不存在或者权限不够将会导致启动异常. 2. 根据日志信息以及status信息来判断问题 通过serv ...
- bzoj 2839 集合计数 —— 二项式反演
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2839 设 \( f(i) \) 为至少 \( i \) 个选择,则 \( f(i) = C_ ...
- laravel 添加自定义类 全局自定义方法 自定义常量
添加自定义类 https://blog.csdn.net/suchfool/article/details/38758367 https://blog.csdn.net/liukai6/article ...