描述

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

格式

输入格式

输入数据只有一行,该行包含若干个数据,之间用半角逗号隔开,表示导弹依次飞来的高度(导弹最多有 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. oc是一个全动态语言,oc的一切都是基于runtime实现的!

    oc是一个全动态语言,oc的一切都是基于runtime实现的! 从以下三方面来理解runtime吧! 1. 传统的面向过程的语言开发,例如c语言.实现c语言编译器很简单,只要按照语法规则实现一个LAL ...

  2. js实时显示系统时间

    刚刚在做后台页面最上面要动态显示时间刚写了这个代码 将这段代码加入<head></head> <!--时间显示代码 --><script>functio ...

  3. easelJS - Cache_vday

    easelJS - Cache_vday $(function() { init(); }); // Cache_vday var canvas; var stage; var container; ...

  4. [源代码] SailingEase .NET Resources Tool (.NET 多语言资源编辑器)

    我在2016年10月发过一篇博客,介绍了我写过的一个多语言资源文件编辑器,并且做为免费软件发布给了出来. 陆续收到了一些朋友的反馈,有朋友很热心提了很多建议和关心的话,还有朋友发红包过来,让我很感动. ...

  5. SoapUI:mock service的使用

    mock service就是服务模拟,当我们的接口完成而服务端还没完成的时候,我们就可以用mock service来替代服务端进行接口测试. 1.1       创建MockService 创建moc ...

  6. 编写JQuery插件-1

    看到这篇文章的人相信大家都学会了jq,或者正在用jq,在这里简单介绍一下jq的插件封装: jQuery的插件主要分为3种类型: 1.封装对象方法的插件 这种插件是将对象的方法封装起来,用于对通过选择器 ...

  7. 【4Large-Style】前端框架设计——Button 的设计思路

    Button 的设计 Button 作为基本的 Web 元素,看似简单,却需要非常用心的设计,因为 Button 作为按钮,是具有多个不同的状态,每种状态都基本上需要进行一些特殊的优化设计,以让组件更 ...

  8. mybatis中mapping文件like查询方式

    方式1: select * from person where name like "%"#{name}"%" 方式2: select * from perso ...

  9. oracle 11G RAC会话故障转移测试

    目前接手的几个项目中,默认使用的oracle RAC数据库服务,均不能实现自动的会话转移,尤其是对于应用的长连接,一旦发生数据库故障,需要重启应用.实际11G具备会话迁移机制,为此做了如下配置测试,供 ...

  10. js-tab选项卡

    说道tab选项卡,顾名思义,就是切换不同内容分类,想必学过前端的都知道,tab有很多方法可以实现,最近刚跟师傅学了一种,感觉很简便,很实用哦.    一.先看一下结果 二.可以根据图来布局,首先上面标 ...