codevs 3369 膜拜
3369 膜拜
神牛有很多…当然…每个同学都有自己衷心膜拜的神牛.
某学校有两位神牛,神牛甲和神牛乙。新入学的N位同学们早已耳闻他们的神话。所以,已经衷心地膜拜其中一位了。
现在,老师要给他们分机房。
但是,要么保证整个机房都是同一位神牛的膜拜者,或者两个神牛的膜拜者人数差不超过M。
另外,现在N位同学排成一排,老师只会把连续一段的同学分进一个机房。老师想知道,至少需要多少个机房。
输入文件第一行包括N和M。
之后N行,每行一个整数,1表示神牛甲的崇拜者,2表示神牛乙的崇拜者。
输出一个整数,表示最小需要机房的数量。
5 1
2
2
1
2
2
2
对于30%的数据,有1≤N,M≤50;
对于100%的数据,有1≤N,M≤2500
本题可以转化为:将一段区间上的所有的点合并,求最少可以合并为多少的区间。
假设区间f[1,4]有4个点:
1、若最后2个能合并,即合并f[3,4],那么合并后的区间数a=f[1,2]+1,最后2个点合并为1个区间,就是那个1;f[1,2]暂且不管。
2、若最后3个能合并,即合并f[2,4],那么合并后的区间数b=f[1,1]+1,最后3个点合并为1个区间,就是那个1;f[1,1]暂且不管。
3、若最后4个能合并,即合并f[1,4],那么合并后的区间数c=f[1,0]+1,很明显,c=1.
请看加红色的部分,发现什么了吗?他们都是从1开始的,这在后面会用到
那么我为什么要倒着看区间能否合并呢?
因为动态规划递推到f[1,4]时,已经计算完了f[1,3],f[1,3]的值是有3个点时最优的,计算f[1,3]之前就计算完了f[1,2],f[1,2]的值是有2个点是最优的,以此类推。
倘若正着判断,我算区间f[1,4],首先看前2个能否合并,即f[1,4]=f[1,2]+f[3,4],前2个若能合并f[1,2]=1,但f[3,4]并不知道。
由此看出倒着推的好处是:另一个区间是从1开始的,而且这个区间在这之前已经确定了最优值,可以实现O(1)复杂度确定上面a、b、c的值(就是直接用)。而正着推得话,可以看到,前面f[3,4]是区间中的一段,不能直接利用,而且f[3,4]的最优解是什么,我们并不知道。
所以动态转移方程:
设当前要排队的区间为f[1,n],那么f[1,n]=min(f[1,m]+1),1<m<=n
初始化条件:答案数组ans[]除0外,都置为极大值,所以不能用memset(ans,127,sizeof(ans))。为什么呢?因为在循环计算f[1,k]时,是通过f[1,k-1]得到前几个的最优值。f[1,1]就可以通过f[0]递推得到,继而推出后面所有的。
那就有人有疑问了:我memset(ans,127,sizeof(ans))之后,另置f[1,1]=1,从第2个开始往后推,不就行了吗?答案是完全可以,个人习惯所致
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,a[],f[];
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
for(int i=;i<=n;i++) f[i]=;//初始化
for(int i=;i<=n;i++)
{
int s1=,s2=,minn=;//s1,当前膜拜1的总人数,s2当前膜拜2的总人数,minn最少可以合并为多少个,即最少房间数
for(int j=i;j;j--)
{
if(a[j]==) s1++;
else s2++;
if(!s1||!s2||abs(s1-s2)<=m)
minn=min(minn,f[j-]+);
}
f[i]=minn;
}
printf("%d",f[n]);
}
codevs 3369 膜拜的更多相关文章
- codevs 3369 膜拜(线型)
3369 膜拜 http://codevs.cn/problem/3369/ 题目描述 Description 神牛有很多…当然…每个同学都有自己衷心膜拜的神牛.某学校有两位神牛,神牛甲和神牛乙.新入 ...
- 膜拜(codevs 3369)
3369 膜拜 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 神牛有很多…当然…每个同学都有自己衷心膜拜的 ...
- CODEVS 必做题:3149、2821、1531、3369、1230
3149 爱改名的小融 2 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description Wikioi上有个人叫小融,他喜 ...
- codevs 3289 花匠
题目:codevs 3289 花匠 链接:http://codevs.cn/problem/3289/ 这道题有点像最长上升序列,但这里不是上升,是最长"波浪"子序列.用动态规划可 ...
- codevs 1082 线段树练习 3(区间维护)
codevs 1082 线段树练习 3 时间限制: 3 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区 ...
- codevs 1285 二叉查找树STL基本用法
C++STL库的set就是一个二叉查找树,并且支持结构体. 在写结构体式的二叉查找树时,需要在结构体里面定义操作符 < ,因为需要比较. set经常会用到迭代器,这里说明一下迭代器:可以类似的把 ...
- codevs 1576 最长上升子序列的线段树优化
题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...
- codevs 1080 线段树点修改
先来介绍一下线段树. 线段树是一个把线段,或者说一个区间储存在二叉树中.如图所示的就是一棵线段树,它维护一个区间的和. 蓝色数字的是线段树的节点在数组中的位置,它表示的区间已经在图上标出,它的值就是这 ...
- codevs 1228 苹果树 树链剖分讲解
题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...
随机推荐
- MyEclipse、Eclipse优化设置
第一步: 取消自动validation validation有一堆,什么xml.jsp.jsf.js等等,我们没有必要全部都去自动校验一下,只是需要的时候才会手工校验一下! 取消方法: windows ...
- Linux 折腾汇集,实时更新
一.Linux教程 入门教程:http://www.92csz.com/study/linux/ 命令大全:http://man.linuxde.net/ 一.界面: 在Ubuntu.Linux Mi ...
- ARC下的所有权修饰符
ARC有效时,id类型必须加上所有权修饰符 下面为三种等效的声明,为了便于和二级指针的情况联系起来,采用第一种. NSError * __weak error = nil; NSError __wea ...
- Git中文版教程
1. 起步 1.1 关于版本控制 1.2 Git 简史 1.3 Git 基础 1.4 命令行 1.5 安装 Git 1.6 初次运行 Git 前的配置 1.7 获取帮助 1.8 总结 2. Git 基 ...
- Linux老是提示compat-libstdc++ is not installed的原因
在一Linux服务器上检查是否安装了一些包时,遇到老是提示"package compat-libstdc++ is not installed" [root@DB-Server ~ ...
- 如何删除或重置spfile中的参数
在ORACLE中,修改spfile中的参数一般非常容易,那么如何删除spfile中的参数呢? 下面我们用一个案例来介绍一下,如何删除spfile中的参数,一种方法就是创建对应的pfile,删除对应的参 ...
- Java并发之ScheduledExecutorService(schedule、scheduleAtFixedRate、scheduleWithFixedDelay)
package com.thread.test.thread; import java.util.Timer; import java.util.TimerTask; import java.util ...
- SQL Server:“数据收缩”详解
1. 数据库的相关属性 在MS中创建数据库时会为数据库分配初始的大小(如下图:数据库和日志两个文件),随着数据库的使用文件会逐渐增大.数据库文件大小的增加有两种方式: 自动增长:在自动增长中可以设置每 ...
- 【转】单表60亿记录等大数据场景的MySQL优化和运维之道 | 高可用架构
此文是根据杨尚刚在[QCON高可用架构群]中,针对MySQL在单表海量记录等场景下,业界广泛关注的MySQL问题的经验分享整理而成,转发请注明出处. 杨尚刚,美图公司数据库高级DBA,负责美图后端数据 ...
- linux 添加用户、权限
# useradd –d /usr/sam -m sam 此命令创建了一个用户sam,其中-d和-m选项用来为登录名sam产生一个主目录/usr/sam(/usr为默认的用户主目录所在的父目录). 假 ...