[线性DP][codeforces-1110D.Jongmah]一道花里胡哨的DP题
题目来源: 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题的更多相关文章
- 严格递增类的dp Codeforces Round #371 (Div. 1) C dp
http://codeforces.com/contest/713 题目大意:给你一个长度为n的数组,每次有+1和-1操作,在该操作下把该数组变成严格递增所需要的最小修改值是多少 思路:遇到这类题型, ...
- Codeforces 1110D Jongmah [DP]
洛谷 Codeforces 我-我我把这-这这题切了??? 说实话这题的确不难,只是我看到有大佬没做出来有点慌-- 突然发现这题是我在洛谷的第500个AC呢.那就更要写篇题解纪念一下了. 思路 容易想 ...
- Codeforces 1110D Jongmah (DP)
题意:你有n个数字,范围[1, m],你可以选择其中的三个数字构成一个三元组,但是这三个数字必须是连续的或者相同的,每个数字只能用一次,问这n个数字最多构成多少个三元组? 解析:首先我们容易发现,我们 ...
- Codeforces 1110D. Jongmah 动态规划
原文链接https://www.cnblogs.com/zhouzhendong/p/CF1110D.html 题意 给定 n 个数,每一个数都是在 [1,m] 里的整数. 从中取出形如 {x,x,x ...
- 【Codeforces 1110D】Jongmah
Codeforces 1110 D 题意:给\(n\)个麻将,每个麻将上有一个\(1..m\)的整数\(a_i\). 现在要将这些麻将们分成一个一个三元组,有两种情况: \([i-1,i,i+1]\) ...
- DP Codeforces Round #303 (Div. 2) C. Woodcutters
题目传送门 /* 题意:每棵树给出坐标和高度,可以往左右倒,也可以不倒 问最多能砍到多少棵树 DP:dp[i][0/1/2] 表示到了第i棵树时,它倒左或右或不动能倒多少棵树 分情况讨论,若符合就取最 ...
- CodeForces 55D Beautiful numbers(数位dp+数学)
题目链接:http://codeforces.com/problemset/problem/55/D 题意:一个美丽数就是可以被它的每一位的数字整除的数. 给定一个区间,求美丽数的个数. 显然这是一道 ...
- Codeforces 55D. Beautiful numbers(数位DP,离散化)
Codeforces 55D. Beautiful numbers 题意 求[L,R]区间内有多少个数满足:该数能被其每一位数字都整除(如12,24,15等). 思路 一开始以为是数位DP的水题,觉得 ...
- Codeforces 479E. Riding in a Lift (dp + 前缀和优化)
题目链接:http://codeforces.com/contest/479/problem/E 题意: 给定一个启示的楼层a,有一个不能去的楼层b,对于你可以去的下一个楼层必须满足你 ...
随机推荐
- CentOS7网络连接问题以及重启网络服务失败
1.重启网络服务失败 在运行“/etc/init.d/network restart”命令时,出现错误“Job for network.service failed. See 'systemctl s ...
- Web | jQuery快速上手
jQuery伴随前端走过一段辉煌的时光,虽然现在已经慢慢的走下顶峰,但是过去的很多项目都是用jQuery写的,它的一些封装思想也非常值得借鉴,懂得jQuery是前端必不可少的. jQuery顶级对象 ...
- vue.js 使用记录(1)
1,for循环 <li @click="toService(type, index)" v-for="(type,index) in typeList" ...
- 页面缓存优化系列一(expires,cache-control 解读)
参考文章:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Cache-Control http://caibaojian.com/s ...
- Yar请求数据接口
//[['u'=>'site.index','d'=>['a'=>2],'k'=>'test']]; public function apiBatch($arr,$timeou ...
- PHP中使用RabiitMQ---各项参数的使用方法
RabbitMQ在PHP使用,我在这里对RabbitMQ的各项方法和参数进行了一些梳理,有不足的地方还望各位大神指点. 想要使用rabbitMQ消息队列,首先需要安装 php_amqp.dll 扩展 ...
- 利用RTTI实现Delphi的多播事件代理研究
我们知道Delphi的每个对象可以包含多个Property,Property中可以是方法,例如TButton.OnClick属性.Delphi提供的仅仅是 一对一的设置,无法直接让TButton.On ...
- 一图看懂hadoop Spark On Yarn工作原理
hadoop Spark On Yarn工作原理
- 93. Balanced Binary Tree [easy]
Description Given a binary tree, determine if it is height-balanced. For this problem, a height-bala ...
- Reflow & Repaint
http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/ http://segmentfault.com/a/1190000002 ...