某DP题目3
题意:
一根数轴上有n只怪物,第i个怪物所在的位置为ai,另有m个特殊点,第i个特殊点所在的位置为bi。你可以对怪物进行移动,若两怪物相邻,那么你不能把他们分开,移动时要看作一个整体。你可以选择向左或向右移动,直到撞到怪物,移动的次数不限制。现在要求最大数量的呆在特殊点上的怪物。 n <= 100000,m <= 2000
分析:
做这题的时候真的非常烦躁,卡在描述状态很久,静下心来思考才能更好地领悟。
由于最终答案与特殊点密切相关,且特殊点是固定不变的,我们不妨以特殊点为基础作转移。接下来我们就可以分情况来考虑了:假设第i只怪兽在特殊点j的左边,那么就需要pos[j]-pos[i]只怪兽填充,即第i+1~i+pos[j]-pos[i]向左移动;反之亦然。
然后我就思考状态,发现无论怎么想,转移都涉及到左移和右移,会出现状态重叠的情况。
那么就要把左移和右移分开,使转移的时候不出现状态重叠的情况。我们令F[i]为前i只怪兽能到达的特殊点的最大数量,而且还带有限制,对于转移怪兽i的时候,怪兽i只能选择不动或者向左移动。那不是说怪兽可以左右移吗?是的,只是怪兽i的向右移是在怪兽i+1~n的转移中,将左右移分开了。这样F[i]所得到的方案必满足所有的怪兽小于等于第i只怪兽的位置pos[i],避免了状态的重叠,这在后面的转移当中至关重要。
那么要如何转移呢?
其实在上面的思考中,已经可以得到答案了。
对于F[i]的转移,只有两种:不动或者向左移动。转移是基于特殊点的,你的转移都是为了去占满更多的特殊点,分类讨论如何占满。
1、不动。枚举位置比怪兽i小的特殊点j,若要占据特殊点j,那么就需要i-(pos[i]-pos[j])~i-1的怪兽右移,转移方程即为:F[i] = max{F[i-(pos[i]-pos[j])-1]+1}。当然还需要注意怪兽连成一块的情况。
2、向左移动。枚举位置特殊点j,以及预处理出位置最大不超过特殊点j的怪兽p。若要占据特殊点j,那么i-p需大于等于pos[j]-pos[p],转移方程即为:F[i] = max{F[p]+1}。这里如果出现连成一块的情况的话,就需要判断第i只怪兽是否在块的最右端,否则,又会出现状态重叠的情况。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream> using namespace std; const int maxn = ;
const int maxm = ;
int n, m, a[maxn], b[maxm];
int belong[maxn], lef_block[maxn], rig_block[maxn], Bcnt;
int p[maxm], f[maxn]; void in()
{
scanf("%d %d", &n, &m);
for (int i = ; i <= n; ++i)
scanf("%d", &a[i]);
for (int i = ; i <= m; ++i)
scanf("%d", &b[i]);
} void prepare()
{
sort(a+, a+n+);
sort(b+, b+m+);
Bcnt = ;
for (int i = ; i <= n; ++i)
{
if (a[i] != a[i-]+ || i == )
{
belong[i] = ++Bcnt;
lef_block[Bcnt] = i;
}
else
belong[i] = Bcnt;
if (a[i+] != a[i]+)
rig_block[Bcnt] = i;
}
for (int i = ; i <= m; ++i)
{
p[i] = p[i-];
while (a[p[i]+] <= b[i])
p[i] ++;
}
} void dp()
{
f[] = ;
for (int i = ; i <= n; ++i)
{
f[i] = f[i-];
for (int j = ; j <= m; ++j){
if (b[j] <= a[i])
{
//part 1 : i don't move, others rig-move
if (i-(a[i]-b[j]) >= )
{
int t = lef_block[belong[i-(a[i]-b[j])]];
f[i] = max(f[t-]+, f[i]);
}
//part 2 : i lef-move
if (b[j]-a[p[j]] <= i-p[j] && rig_block[belong[i]] == i)
{
f[i] = max(f[p[j]]+, f[i]);
}
}
else
break ;
}
}
printf("%d\n", f[n]);
} void work()
{
prepare();
dp();
} int main()
{
freopen("a.in", "r", stdin);
freopen("a.out", "w", stdout);
in();
work();
return ;
}
某DP题目3的更多相关文章
- DP题目列表/弟屁专题
声明: 1.这份列表不是我原创的,放到这里便于自己浏览和查找题目. ※最近更新:Poj斜率优化题目 1180,2018,3709 列表一:经典题目题号:容易: 1018, 1050, 1083, 10 ...
- dp题目列表
此文转载别人,希望自己能够做完这些题目! 1.POJ动态规划题目列表 容易:1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 11 ...
- dp题目
从别的地方看来,最近一直在啃DP,有个目标,更有动力了. 1.Robberies 连接 :http://acm.hdu.edu.cn/showproblem.php?pid=2955 背包; ...
- 插头DP题目泛做(为了对应WYD的课件)
题目1:BZOJ 1814 URAL 1519 Formula 1 题目大意:给定一个N*M的棋盘,上面有障碍格子.求一个经过所有非障碍格子形成的回路的数量. 插头DP入门题.记录连通分量. #inc ...
- 很好的一个dp题目 Codeforces Round #326 (Div. 2) D dp
http://codeforces.com/contest/588/problem/D 感觉吧,这道题让我做,我应该是不会做的... 题目大意:给出n,L,K.表示数组的长度为n,数组b的长度为L,定 ...
- 两道很好的dp题目【4.29考试】
A 问题描述: 对于一个排列,考虑相邻的两个元素,如果后面一个比前面一个大,表示这个位置是上升的,用I表示,反之这个位置是下降的,用D表示.如排列3,1,2,7,4,6,5可以表示为DIIDID. 现 ...
- 题目1453:Greedy Tino(dp题目)
题目链接:http://ac.jobdu.com/problem.php?pid=1453 详解链接:https://github.com/zpfbuaa/JobduInCPlusPlus 参考代码: ...
- 题目1452:搬寝室(dp题目)
题目链接:http://ac.jobdu.com/problem.php?pid=1452 详解链接:https://github.com/zpfbuaa/JobduInCPlusPlus 参考代码: ...
- 题目1042:Coincidence(最长公共子序列 dp题目)
题目链接:http://ac.jobdu.com/problem.php?pid=1042 详解链接:https://github.com/zpfbuaa/JobduInCPlusPlus 参考代码: ...
- 概率dp+期望dp 题目列表(一)
表示对概率和期望还不是很清楚定义. 目前暂时只知道概率正推,期望逆推,然后概率*某个数值=期望. 为什么期望是逆推的,例如你求到某一个点的概率我们可以求得,然后我们只要运用dp从1~n每次都加下去就好 ...
随机推荐
- 无key值的json数组解析
[ [ { "cartId": 9223, "factoryId": 143, ...
- python基础之上下文管理器
前言 关于计算器运行的上下文的概念,我的理解也不是很深:按我的理解就是程序在运行之前,其所需要的资源,运行环境等都会被序列化,然后加入到CPU的任务队列中,等待调度系统分配时间片执行.下面谈谈pyth ...
- .NET连接Oracle的方法
.NET连接Oracle的方法 方式1:直接利用.NET的oracle驱动连接 引用System.data.oracleclient; using System.data.oracleclient; ...
- 使用angluar-cli的ng g component home指令出现的错误
Error: ELOOP: too many symbolic links encountered, stat '/Users/zzy/angular/taskmgr/node_modules/@an ...
- NFS生产场景优化
1.硬件上多块网卡bond,增加吞吐量,至少千兆.sas/ssd磁盘组raid5或raid10 2.服务端配置:/data 172.16.1.0/24(rw,sync,all_squash,anonu ...
- python抓取链家房源信息
闲着没事就抓取了下链家网的房源信息,抓取的是北京二手房的信息情况,然后通过网址进行分析,有100页,并且每页的url都是类似的 url = 'https://bj.lianjia.com/ershou ...
- Nginx 502错误:upstream sent too big header while reading response header from upstream
原因: 在使用Shiro的rememberMe功能时,服务器返回response的header部分过大导致. 解决方法: https://stackoverflow.com/questions/238 ...
- EasyUi – 1.入门
1.页面引用. jquery,easyui,主题easyui.css,图标ico.css,语言zh_CN.js <script src="Scripts/jquery-easyui-1 ...
- 清除(设置)eclipse的workspace记录
在eclipse文件夹中找到这个文件即可: //eclipse/configuration/.settings/org.eclipse.ui.ide.prefs 用记事本打开这个文件.如果你是第一次打 ...
- IEEEXtreme 10.0 - N-Palindromes
这是 meelo 原创的 IEEEXtreme极限编程大赛题解 Xtreme 10.0 - N-Palindromes 题目来源 第10届IEEE极限编程大赛 https://www.hackerra ...