描述

某国为了防御敌国的导弹袭击,研发出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试验阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。

格式

输入格式

输入数据只有一行,该行包含若干个数据,之间用半角逗号隔开,表示导弹依次飞来的高度(导弹最多有 20 枚,其高度为不大于 30000 的正整数)。

输出格式

输出数据只有一行,该行包含两个数据,之间用半角逗号隔开。第一个数据表示这套系统最多能拦截的导弹数;第二个数据表示若要拦截所有导弹至少要再添加多少套这样的系统。

样例1

样例输入1

389,207,155,300,299,170,158,65

样例输出1

   6,1

很明显这题首先需要求最长上升序列,这题有比较多的做法,我这里选用LCS(最长公共子序列)做法,但问题是最长公共子序列是求A={a1,a2,a3...an}与B={b1,b2,b3....bm}的最长公共子序列,这里只有一个序列串。

所以首先我们需要copy源串,然后对副本进行降序排序,得到一个序列,然后两个序列进行LCS就可以得出最长下降序列了。

然后回溯找出LCS中求出的串,对源串进行删除,最后递归执行直到源串为0就好了。

Java AC Code:
public class Main {
//最长下降序列长度
public static int m = 0;
//还需要多少飞弹
public static int need = 0; public static void main( String[] args ) { Scanner sc = new Scanner( System.in );
while( sc.hasNext() ) {
m=0;
need=0;
String str = sc.nextLine();
int[] nums = getSplits( str, "," );
List<Integer> list = new ArrayList<Integer>();
for( int i = 0; i < nums.length; i++ ) {
list.add( nums[ i ] );
}
LCS( nums,list );
System.out.println( m+","+(need-1) );
}
}
//进行LCS
public static void LCS( int[] nums, List<Integer> list ) {
int[] sortNums = new int[ nums.length ];
int[][] b = new int[ nums.length + 1 ][ nums.length + 1 ];
int n = nums.length;
for( int i = 0; i < n; i++ ) {
sortNums[ i ] = nums[ i ];
}
Arrays.sort( sortNums );
int[] descNums = new int[ n ];
for( int i = 0; i < n; i++ ) {
descNums[ i ] = sortNums[ n - i - 1 ];
}
int[][] lcs = new int[ n + 1 ][ n + 1 ];
for( int i = 1; i <= n; i++ ) {
for( int j = 1; j <= n; j++ ) {
if( nums[ i - 1 ] == descNums[ j - 1 ] ) {
lcs[ i ][ j ] = lcs[ i - 1 ][ j - 1 ] + 1;
b[ i ][ j ] = 0;
} else {
if( lcs[ i - 1 ][ j ] > lcs[ i ][ j - 1 ] ) {
lcs[ i ][ j ] = lcs[ i - 1 ][ j ];
b[ i ][ j ] = -1;
} else {
lcs[ i ][ j ] = lcs[ i ][ j - 1 ];
b[ i ][ j ] = 1;
}
}
}
} //递归求need,并且判断获取最长的下降序列。
m = lcs[n][n] > m?lcs[n][n]:m;
while(list.size() !=0){
printLCS( b, nums, n, n, list );
int[] newNums = new int[list.size()];
for(int i=0;i<list.size();i++){
newNums[i] = list.get( i);
}
LCS(newNums,list);
need++;
}
} //输入分片
public static int[] getSplits( String str, String pattern ) {
String[] splits = str.split( pattern );
int[] ret = new int[ splits.length ];
for( int i = 0; i < ret.length; i++ ) {
ret[ i ] = Integer.parseInt( String.valueOf( splits[ i ] ) );
}
return ret;
}
//回溯输出最长序列。
public static void printLCS( int[][] b, int[] nums, int i, int j,List<Integer> list) {
if( i == 0 || j == 0 )
return;
else if( b[ i ][ j ] == 0 ) {
printLCS( b, nums, i - 1, j - 1,list );
list.remove( new Integer(nums[i-1]) );
} else if( b[ i ][ j ] == -1 ) {
printLCS( b, nums, i - 1, j,list );
} else {
printLCS( b, nums, i, j - 1,list);
}
}
}

关于LCS算法的具体实现,自行百度啦,主要就是进行矩阵Dp,判断相等于不相等时候的选择大小。

[vijosP1303]导弹拦截(最长上升子序列转LCS)的更多相关文章

  1. 洛谷 - P1020 - 导弹拦截 - 最长上升子序列

    https://www.luogu.org/problemnew/show/P1020 终于搞明白了.根据某定理,最少需要的防御系统的数量就是最长上升子序列的数量. 呵呵手写二分果然功能很多,想清楚自 ...

  2. 最长公共子序列问题 (LCS)

    给定两个字符串S和T.求出这两个字符串最长的公共子序列的长度. 输入: n=4 m=4 s="abcd" t="becd" 输出: 3("bcd&qu ...

  3. 动态规划法(十)最长公共子序列(LCS)问题

    问题介绍   给定一个序列\(X=<x_1,x_2,....,x_m>\),另一个序列\(Z=<z_1,z_2,....,z_k>\)满足如下条件时称为X的子序列:存在一个严格 ...

  4. 动态规划经典——最长公共子序列问题 (LCS)和最长公共子串问题

    一.最长公共子序列问题(LCS问题) 给定两个字符串A和B,长度分别为m和n,要求找出它们最长的公共子序列,并返回其长度.例如: A = "HelloWorld"    B = & ...

  5. 【Luogu P1439】最长公共子序列(LCS)

    Luogu P1439 令f[i][j]表示a的前i个元素与b的前j个元素的最长公共子序列 可以得到状态转移方程: if (a[i]==b[j]) dp[i][j]=dp[i-1][j-1]+1; d ...

  6. 最长公共子序列(LCS)、最长递增子序列(LIS)、最长递增公共子序列(LICS)

    最长公共子序列(LCS) [问题] 求两字符序列的最长公共字符子序列 问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字 ...

  7. 清橙 A1120 拦截导弹 -- 动态规划(最长上升子序列)

    题目地址:http://oj.tsinsen.com/A1120 问题描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但 ...

  8. VijosP1303 导弹拦截

    背景 实中编程者联盟为了培养技术精湛的后备人才,必须从基础题开始训练. 描述 某国为了防御敌国的导弹袭击,研发出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度, ...

  9. 【线型DP模板】最上上升子序列(LIS),最长公共子序列(LCS),最长公共上升子序列(LCIS)

    BEGIN LIS: 一个数的序列bi,当b1 < b2 < … < bS的时候,我们称这个序列是上升的.对于给定的一个序列(a1, a2, …, aN),我们可以得到一些上升的子序 ...

随机推荐

  1. HTTP Session学习

    session在web开发中是一个非常重要的概念,这个概念很抽象,很难定义,也是最让人迷惑的一个名词,也是最多被滥用的名字之一,在不同的场合,session一次的含义也很不相同.这里只探讨HTTP S ...

  2. Java泛型中的通配符的使用

    package com.srie.testjava; import java.util.ArrayList; import java.util.List; public class TestClass ...

  3. webpack 学习心得(一)

    Webpack 是一个模块打包器.它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源. 因为本人也正在学习webpack ,所以此篇文章比较入门. 首先你想使用webp ...

  4. getstyle() 获取样式

    问题:在js动画中,如果元素设置了border,padding等,获取到的样式是盒子的样式,这样会影响动画的正常显示. 解决方案一:在元素的行内添加样式  如 <div style=" ...

  5. Webappbuilder开发快速预览

    Webappbuilder开发快速预览 by 李远祥 Webappbuilder for ArcGIS 是由ArcGIS JavaScripit API和dojo创建的,它允许通过创建自己的widge ...

  6. matlab中使用elseif和if嵌套的对比

    % 目标: % 判定成绩等级 %定义变量 % 输入:分数grade %清除变量或指令 clc; % 允许用户输入参数 disp ('该功能练习if语句'); disp ('输入你的成绩,系统将判定等级 ...

  7. 制作 OpenStack Windows 镜像 - 每天5分钟玩转 OpenStack(152)

    这是 OpenStack 实施经验分享系列的第 2 篇. OpenStack 通过 Glance 镜像部署 instance,上一节我们介绍了 linux 镜像制作方法,windows 镜像与 lin ...

  8. oracle 游标的使用

    额,一直提起游标就头疼,总感觉是很高大上的东西,望而却步... 今天要做的东西涉及到了实时更新数据,要用到JOB 存储过程  游标 通过在网上查资料,请教同事,也开始继续深入oracle,,,,小菜啊 ...

  9. JUnit与JMock学习

    JUnit与JMock学习 测试驱动编程和持续集成部署应该说是现在软件开发者的必备武器,不过跟其他很多好东西一样,在我们公司的推广总要慢上一拍,毕竟老板看的是你能够把功能实现好让客户满意,所以能不折腾 ...

  10. C#委托简介

    C#中委托是一种引用类型,该引用类型与其他引用类型不同,在委托对象的引用中存放的不是对数据的引用而是存放对方法的引用,即委托的内部包含一个指向某个方法的指针.通过使用委托把方法的引用封装在委托对象中, ...