两道NOIP里的DP题目~
拦截导弹 来源:NOIP1999(提高组) 第一题
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入数据为两行,
第一行为导弹的数目N(n<=1000)
第二行导弹依次飞来的高度,所有高度值均为不大于30000的正整数。
1.输出只有一行是这套系统最多能拦截的导弹数和 2.要拦截所有导弹最少要配备这种导弹拦截系统的套数。两个数据之间用一个空格隔开
样例输入
8
389 207 155 300 299 170 158 65
样例输出
6 2
可以先将这个问题分作两个小问题解决,第一个小问明显是要求出最长非严格下降子序列,因为它要保证每一发炮弹都不能高于前一发的高度
第二个小问则是要你求出最长严格上升子序列,这个结论就不能明显的出啦,因为一开始我也想不出来,也是看了题解才懂。
证明过程:
目标首先是要保证所有的目标都要摧毁,既然每个目标都要被摧毁,那么如果这个被摧毁的目标的后面的目标比它搞的话,摧毁这个目标
的导弹系统就不能摧毁它后面的目标了。从而,我们所需要的炮弹系统的高度必定是严格上升的序列~又因为要摧毁所有的目标,所以为最长严格
上升子序列~
ps:这道题的数据目测比较弱,第二问我用非严格上升去做也能ac。。。。。
附上ac的c++代码:
#include <cstdio>
#include <iostream> using namespace std;
const int maxn = ;
int a[maxn],inc[maxn],dece[maxn];
const int INF = 0x3f3f3f3f;
int main(){
int n;
while(~scanf("%d",&n)){
int INC = ,DEC = ;
fill(a,a + maxn,);
fill(inc,inc + maxn,);
fill(dece,dece + maxn,);
for(int i = ;i <= n;++i)
scanf("%d",&a[i]);
a[] = INF;//注意 初始化
for(int i = ;i <= n;++i){
for(int j = ;j <= i-;++j){
if(a[i] <= a[j]&&dece[i] < dece[j] + ) //非严格下降子序列
dece[i] = dece[j] + ;
}
//cout<<dece[i];
DEC = max(DEC,dece[i]);
}
//cout<<endl;
a[] = -INF;//注意重新初始化
for(int i = ;i <= n;++i){
for(int j = ;j <= i-;++j){
if(a[i] > a[j]&&inc[i] < inc[j] + ) //严格上升子序列
inc[i] = inc[j] + ;
}
//cout<<inc[i];
INC = max(INC,inc[i]);
}
//cout<<endl;
printf("%d %d\n",DEC,INC);
}
return ;
}
合唱队形 来源:NOIP2004(提高组) 第一题
N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高满足T1<...<Ti>Ti+1>…>TK(1<=i<=K)。
你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。
输入的第一行是一个整数N(2<=N<=100),表示同学的总数。第一行有n个整数,用空格分隔,第i个整数Ti(130<=Ti<=230)是第i位同学的身高(厘米)。
输出包括一行,这一行只包含一个整数,就是最少需要几位同学出列。
样例输入
8
186 186 150 200 160 130 197 220
样例输出
4
思路:
设dec[i] 是以a[i] 为结尾的最长严格上升序列,inc[i] 是以a[i]开始的最长严格下降序列,所以 最终答案是 n - max(dec[i] + inc[i] - 1);
dec[i] 和inc[i] 仿照上面那道题 即可,不过注意代码细节有所不同
#include <cstdio>
#include <iostream> using namespace std;
const int maxn = ;
int a[maxn],inc[maxn],dece[maxn];
const int INF = 0x3f3f3f3f;
int main(){
int n;
while(~scanf("%d",&n)){
int INC = ,DEC = ;
fill(a,a + maxn,);
fill(inc,inc + maxn,);
fill(dece,dece + maxn,);
for(int i = ;i <= n;++i)
scanf("%d",&a[i]);
a[] = -INF;//注意 初始化
for(int i = ;i <= n;++i){
for(int j = ;j <= i-;++j){
if(a[i] > a[j]&&dece[i] < dece[j] + ) //
dece[i] = dece[j] + ;
}
}
a[n+] = -INF;//注意重新初始化
for(int i = n;i >= ;--i){
for(int j = n+;j >= i + ;--j){
if(a[i] > a[j]&&inc[i] < inc[j] + ) //
inc[i] = inc[j] + ;
}
}
int ans = ;
for(int i = ;i <= n;i++){
ans = max(ans,dece[i] + inc[i]);
}
printf("%d\n",n - ans + );
}
return ;
}
两道NOIP里的DP题目~的更多相关文章
- 两道很好的dp题目【4.29考试】
A 问题描述: 对于一个排列,考虑相邻的两个元素,如果后面一个比前面一个大,表示这个位置是上升的,用I表示,反之这个位置是下降的,用D表示.如排列3,1,2,7,4,6,5可以表示为DIIDID. 现 ...
- 你所不知道的库存超限做法 服务器一般达到多少qps比较好[转] JAVA格物致知基础篇:你所不知道的返回码 深入了解EntityFramework Core 2.1延迟加载(Lazy Loading) EntityFramework 6.x和EntityFramework Core关系映射中导航属性必须是public? 藏在正则表达式里的陷阱 两道面试题,带你解析Java类加载机制
你所不知道的库存超限做法 在互联网企业中,限购的做法,多种多样,有的别出心裁,有的因循守旧,但是种种做法皆想达到的目的,无外乎几种,商品卖的完,系统抗的住,库存不超限.虽然短短数语,却有着说不完,道不 ...
- 与高精死杠的几天——记两道简单的高精dp
(同样也是noip往年的题 1.矩阵取数游戏 题目链接[Luogu P1005 矩阵取数游戏] \(\mathcal{SOLUTION}:\) 通过对题目条件的分析,我们可以发现,每一行取数对答案的 ...
- leetcode简单题目两道(2)
Problem Given an integer, write a function to determine if it is a power of three. Follow up: Could ...
- 方阵里面的dp
打了一场luogu的信心赛,惊讶地发现我不会T2,感觉像这样在矩阵里面的dp看起来很套路的样子,但是仔细想想还是有很多需要注意的细节. 又想到之前貌似也考过一些类似的题目 然而我并没有改 ,于是打算补 ...
- 两道面试题,带你解析Java类加载机制
文章首发于[博客园-陈树义],点击跳转到原文<两道面试题,带你解析Java类加载机制> 在许多Java面试中,我们经常会看到关于Java类加载机制的考察,例如下面这道题: class Gr ...
- 【转】两道面试题,带你解析Java类加载机制(类初始化方法 和 对象初始化方法)
本文转自 https://www.cnblogs.com/chanshuyi/p/the_java_class_load_mechamism.html 关键语句 我们只知道有一个构造方法,但实际上Ja ...
- 几道经典的SQL笔试题目
几道经典的SQL笔试题目(有答案) (1)表名:购物信息 购物人 商品名称 数量 A 甲 2 B 乙 ...
- ACM/ICPC 之 SPFA范例两道(POJ3268-POJ3259)
两道以SPFA算法求解的最短路问题,比较水,第二题需要掌握如何判断负权值回路. POJ3268-Silver Cow Party //计算正逆最短路径之和的最大值 //Time:32Ms Memory ...
随机推荐
- 笔试算法题(44):简介 - 动态规划(Dynamic Programming)
议题:动态规划(Dynamic Programming) 分析: DP主要用于解决包含重叠子问题(Overlapping Subproblems)的最优化问题,其基本策略是将原问题分解为相似的子问题, ...
- 笔试算法题(15):-1到N中包含1的数字的个数 & 连续和为N的序列
出题:输入一个整数N,求从1到N这N个整数的十进制表示中‘1’出现的次数: 分析: 从左向右处理string表示的数字:当前数字长度为n,判断最左边一位数字字符: 如果是0,则直接递归下一位: 如果是 ...
- Python中的列表(5)
1.使用函数 range() 创建一个数字列表 for value in range(1,5): print(value) console: 我们发现,它并不会打印数字5,因为 range() 函数, ...
- [luoguP1962] 斐波那契数列(矩阵快速幂)
传送门 解析详见julao博客连接 http://worldframe.top/2017/05/10/清单-数学方法-——-矩阵/ ——代码 #include <cstdio> #incl ...
- CodeForces788B 欧拉路
B. Weird journey time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...
- Jquery为DIV添加点击事件,Jquery为a标签超链接添加点击事件
<div>1</div> <div>2</div> <div>3</div> <div>4</div> ...
- [bzoj1324]Exca王者之剑_最小割
Exca王者之剑 bzoj-1324 题目大意:题目链接. 注释:略. 想法: 最小割经典模型. 所有格子向源点连权值为格子权值的边. 将棋盘黑白染色后白点反转源汇. 如果两个格子相邻那么黑点向白点连 ...
- Servlet的服务端响应
以下内容引用自http://wiki.jikexueyuan.com/project/servlet/server-response.html: 当一个Web服务器对浏览器响应一个HTTP请求时,响应 ...
- 【c++】C语言中volatile关键字的作用
因为访问寄存器要比访问内存单元快的多,所以编译器一般都会作减少存取内存的优化,但有可能会读脏数据.当要求使用volatile声明变量值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从 ...
- 【c++】【转】如何只在heap上创建对象,如何只在stack上建立对象?
http://www.cnblogs.com/chio/archive/2007/10/23/934335.html http://blog.csdn.net/szchtx/article/detai ...