题目来源: Codeforces - 1110D

题意:你有n张牌(1,2,3,...,m)你要尽可能多的打出[x,x+1,x+2] 或者[x,x,x]的牌型,问最多能打出多少种牌

思路:

1.三组[x,x+1,x+2]的效果等同于 [x,x,x],[x+1,x+1,x+1],[x+2,x+2,x+2],所以每种顺子牌型最多打2次(如果多于2次,可以被少于3次的方案替代掉,因此忽略)

2.对于每一种牌,用途只有四种。[i-2,i-1,i], [i-1,i,i+1], [i,i+1,i+2], [i,i,i]

 我们可以枚举每张牌在四种用途里分别投入了多少

 由简单的容斥原理,我们只需要枚举三种顺子牌型分别有x,y,z组,那么[i,i,i]就有(c[i]-x-y-z)/3组

 于是我们就有了线性dp的思路

 如果建立dp[maxn][3][3][3],dp[i][x][y][z]表示在第i阶段,第i张牌用来组成三种牌型分别有x,y,z组的最优结果,有dp[i][x][y][z] = max{dp[i-1][?][x][y]} + z + (c[i] - x - y - z) / 3, ans = max{dp[n][?][0][0])

 AC代码:

 #include <bits/stdc++.h>

 using namespace std;
const int maxn = 1e6 + ;
int n;
int c[maxn];
int dp[maxn][][][];
int main(){
//freopen("data.in","r",stdin);
ios::sync_with_stdio(false);
cin.tie();
int cc,t;
cin >> cc >> n;
for(int i = ; i <= cc; i++){
cin >> t;
c[t]++;
}
for(int i = ; i <= n; i++){
for(int x = ; x < ; x++){
for(int y = ; y < ; y++){
for(int z = ; z < ; z++){
if(x + y + z > c[i])continue;
for(int t = ; t < ; t++)
dp[i][x][y][z] = max(dp[i][x][y][z], dp[i-][t][x][y] + z + (c[i]-x-y-z)/);
}
}
}
}
int ans;
for(int t = ; t < ; t++){
ans = max(ans, dp[n][t][][]);
}
cout << ans << endl;
return ;
}

3.仔细观察上面的代码,我们发现在状态转移过程中,两个方程中都有[x][y],状态之间的联系太过紧密,可以尝试优化一下

 如果建立dp[maxn][3][3],少了一个维度,dp[i][x][y] 表示有x组[i-1,i,i+1],y组[i,i+1,i+2]时的最优结果,有dp[i][x][y] = max{dp[i-1][?][x] + y + (c[i] - ? - x - y)/3}

 AC代码:

 #include <bits/stdc++.h>

 using namespace std;

 const int maxn = 1e6 + ;
int n;
int c[maxn];
int dp[maxn][][];
int main(){
//freopen("data.in","r",stdin);
ios::sync_with_stdio(false);
cin.tie();
int cc,t;
cin >> cc >> n;
for(int i = ; i <= cc; i++){
cin >> t;
c[t]++;
}
for(int i = ; i <= n; i++){
for(int x = ; x < ; x++){
for(int y = ; y < ; y++){
for(int z = ; z < ; z++){
if(x + y + z > c[i])continue;
dp[i][y][z] = max(dp[i][y][z], dp[i-][x][y] + z + (c[i]-x-y-z)/);
}
}
}
}
int ans = dp[n][][];
cout << ans << endl;
return ;
}

4.由于每一阶段的决策只与上一阶段有关,可以使用滚动数组进行进一步优化。

[线性DP][codeforces-1110D.Jongmah]一道花里胡哨的DP题的更多相关文章

  1. 严格递增类的dp Codeforces Round #371 (Div. 1) C dp

    http://codeforces.com/contest/713 题目大意:给你一个长度为n的数组,每次有+1和-1操作,在该操作下把该数组变成严格递增所需要的最小修改值是多少 思路:遇到这类题型, ...

  2. Codeforces 1110D Jongmah [DP]

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

  3. Codeforces 1110D Jongmah (DP)

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

  4. Codeforces 1110D. Jongmah 动态规划

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF1110D.html 题意 给定 n 个数,每一个数都是在 [1,m] 里的整数. 从中取出形如 {x,x,x ...

  5. 【Codeforces 1110D】Jongmah

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

  6. DP Codeforces Round #303 (Div. 2) C. Woodcutters

    题目传送门 /* 题意:每棵树给出坐标和高度,可以往左右倒,也可以不倒 问最多能砍到多少棵树 DP:dp[i][0/1/2] 表示到了第i棵树时,它倒左或右或不动能倒多少棵树 分情况讨论,若符合就取最 ...

  7. CodeForces 55D Beautiful numbers(数位dp+数学)

    题目链接:http://codeforces.com/problemset/problem/55/D 题意:一个美丽数就是可以被它的每一位的数字整除的数. 给定一个区间,求美丽数的个数. 显然这是一道 ...

  8. Codeforces 55D. Beautiful numbers(数位DP,离散化)

    Codeforces 55D. Beautiful numbers 题意 求[L,R]区间内有多少个数满足:该数能被其每一位数字都整除(如12,24,15等). 思路 一开始以为是数位DP的水题,觉得 ...

  9. Codeforces 479E. Riding in a Lift (dp + 前缀和优化)

    题目链接:http://codeforces.com/contest/479/problem/E 题意:         给定一个启示的楼层a,有一个不能去的楼层b,对于你可以去的下一个楼层必须满足你 ...

随机推荐

  1. Filters in ASP.NET Core (转自MSDN)

    Filters in ASP.NET Core MVC allow you to run code before or after specific stages in the request pro ...

  2. 安卓 通过www读取Application.persistentDataPath

    今天在读取Application.persistentDataPath路径下的图片时,在前面加上“file:///” 例如 #if UNITY_EDITOR || UNITY_STANDALONE r ...

  3. Android 把url生成二维码并贴到给定的底图上

    主要是用到了com.google.zxing jar包生成二维码的功能,这个jar包需要自己接下载 直接上代码 public static Bitmap CreateBinaryCodeImageBy ...

  4. Java中的集合框架-Collection(二)

    上一篇<Java中的集合框架-Collection(一)>把Java集合框架中的Collection与List及其常用实现类的功能大致记录了一下,本篇接着记录Collection的另一个子 ...

  5. macOS:按钮类型

    for (int i = 0; i < 10; i++) { for (int j = 1; j < 16; j++) { NSButton *btn = [[NSButton alloc ...

  6. PHP目前比较常见的五大运行模式

    做 php 开发的应该都知道 php 运行模式概念吧,本文将要和大家分享的是关于php目前比较常见的五大运行模式:包括cgi .fast-cgi.cli.isapi.apache模块的DLL ,下面作 ...

  7. Redis 之复制-初入江湖

    一.前言 在分布式系统中,为了解决单点问题,通常会把数据复制多个副本部署到其他机器,满足故障恢复合负载均衡等需求.Redis也是如此,它为我们提供了复制的功能,实现了相同数据的多个Redis副本.复制 ...

  8. 第一篇随笔, 正在做 ESP32 , STM32 , 树莓派 RaspberryPi 的创客工具

    先随便写写一些思路, 以后再整理. 这段时间笔者做了一些硬件开发, 领悟了一些事情. 1 - 在常规创客的角度上, 硬件开发所需的知识面比较广, 非常广, 但不算太深. 2 - 发现硬件开发由于其特殊 ...

  9. elasticsearch_dsl 的nested

    在工作中会碰到这样的一个需求,mapping中定义的类型是nested { "judgement":{ "mappings":{ "content&q ...

  10. 微信小程序真机预览跟本地不同的问题。原文地址:https://blog.csdn.net/qq_27187991/article/details/69664247/

    微信小程序中出现最多的一个问题,就是真机跟本地不同:我简单列举一些我发现的原因,给大家参考,大家也可以把自己发现的东西回复给我,给我参考: 本地看不到数据,就先让本地能看到数据,再看本帖....特别提 ...