题目

描写叙述

Long , long ago ,country A invented a missile system to destroy the missiles from their enemy . That system can launch only one missile to destroy multiple missiles if the heights of all the missiles
form a non-decrease sequence .

But recently , the scientists found that the system is not strong enough . So they invent another missile system . The new system can launch one single missile to destroy many more enemy missiles . Basically , the system can destroy the missile from near
to far . When the system is begun , it chooses one enemy missile to destroy , and then destroys a missile whose height is lower and farther than the first missile . The third missile to destroy is higher and farther than the second missile … the odd missile
to destroy is higher and farther than the previous one , and the even missile to destroy is lower and farther than the previous one .

Now , given you a list of the height of missiles from near to far , please find the most missiles that can be destroyed by one missile launched by the new system .

输入

The input contains multiple test cases .

In each test case , first line is an integer n ( 0<n<=1000 ) , which is the number of missiles to destroy . Then follows one line which contains n integers ( <=109 ) , the height of the missiles followed by distance .

The input is terminated by n = 0 .

输出

For each case , print the most missiles that can be destroyed in one line .

例子输入

4

5 3 2 4

3

1 1 1

0

例子输出

3

1

大意:

一种导弹,能够摧毁敌军的导弹。 可是有一种奇怪的设定:

敌军导弹由远及近过来时, 此导弹能够选择当中的一颗開始摧毁, 然后接着摧毁比上一个远的而且高度较低的导弹,然后再摧毁更远的但高度较高的导弹,如此往复。

求最多打到的导弹数量。

思路

 这道题给人的第一感觉就是单调递增子序列的变形 。 也就是最长凹凸子序列。。

 非常明显就是dp问题。

 求解dp问题的关键就是梳理出状态转移方程。 对于单调递增子序列问题, 状态转移方程为:
  
                    dp[i] = max (dp[k]+1 )    (k<i && v[k] < v[i]) ;

也就是,以当前点为结尾的的最长单调子序列, 是这个点之前的;值小于这个点的; 之中局部最优的+1 。

对于如今的问题,由于不是单调递增的,所以要对dp方程进行变形 。

以为导弹的规律是高低切换的,所以每一个导弹可能作为lower被击落, 也有可能作为higher被击落。  作为不同身份被击落可能有不同的最优解,同一时候也会影响后面的导弹。

因此,这里须要保存两个状态,简单的约定为:
                        a[i] :  导弹i作为higher被击落时的最优解
                        b[i] :  导弹作为lower   被击落时的最优解

相对的,新的dp方程为:
                      a[i]  =   max{b[k]+1}       (k<i&&v[k]<v[i])    
                      b[i] =    max{a[k]+1}       (k<i&&v[k]>v[i])

初始化 a[0]=1 //第一个击中i=0就可以得到1这个解
             b[0]=0 // 由于题意第一个击中较高的, 所以排在位置0的导弹不可能作为lower被击落。 作为lower的最优解为0.


完整代码:

之前写的代码,非常不规范。凑合看吧
#include<iostream>
using namespace std;
int a[1001],b[1001];
int str[1001];
int main()
{
//freopen("aa.txt","r",stdin);
int n,i,j,max2;
while(scanf("%d",&n)!=EOF)
{
if(!n)
break;
for(i=0;i<n;i++)
scanf("%d",&str[i]);
for(i=0;i<n;i++)
{
a[i]=1; //as higher
b[i]=0; //as lower
}
for(i=1;i<n;i++)
{
int max=1,max1=0;
for(j=0;j<i;j++)
{
if(str[i]>str[j])
{
a[i]=b[j]+1;
if(a[i]>max)
max=a[i];
}
if(str[i]<str[j])
{
b[i]=a[j]+1;
if(b[i]>max1)
max1=b[i];
}
}
b[i]=max1;
a[i]=max;
}
max2=a[0];
for(i=0;i<n;i++)
{
if(a[i]>max2)
max2=a[i];
if(b[i]>max2)
max2=b[i];
}
cout<<max2<<endl;
}
}

验证

    为什么程序会保证得出的最优解是 “第一个击中higher”的情况呢?
     能够这样证明: 由于全部位置i ,默认的b[i] 都为 0 。  假设最优解 出如今lower位置, 即b[k] 为全部a[] b[]中的最大值,则说明k前面必存在一个j使a[j] > b[k] . 也就是说有个higher先被击中。

   简单測试。

  




Missile:双状态DP的更多相关文章

  1. [Swust OJ 1084]--Mzx0821月赛系列之情书(双线程dp)

    题目链接:http://acm.swust.edu.cn/problem/1084/ Time limit(ms): 1000 Memory limit(kb): 65535   Descriptio ...

  2. 72. Edit Distance(困难,确实挺难的,但很经典,双序列DP问题)

    Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2 ...

  3. 洛谷P2770 双路DP // 网络流

    https://www.luogu.org/problemnew/show/P2770 第一眼看过去,觉得这不是一个经典的双路DP模型吗,将一条过去一条回来互不相交的路径看作是起点出发了两条路径一起走 ...

  4. hdu 4614 pieces 状态DP

    题意:给你一个长度小于等于16的字符串,每次可以删除一个回文传,问你最少删除干净的字数. 状态+dp dp[i] = min(dp[i],dp[j]+dp[j^i]);(j是i的字串): 连接:htt ...

  5. hdu 4778 Gems Fight! 博弈+状态dp+搜索

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4102743.html 题目链接:hdu 4778 Gems Fight! 博弈+状态dp+搜 ...

  6. POJ 3254 压缩状态DP

    题意:一个矩形网格,可以填0或1, 但有些位置什么数都不能填,要求相邻两个不同时为1,有多少种填法.矩形大小最大 12*12. 压缩状态DP大多有一个可行的state的范围,先求出这个state范围, ...

  7. Codevs 1427 特种部队(双路DP)

    1427 特种部队 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 黄金 Gold 题目描述 Description 某特种部队接到一个任务,需要潜入一个仓库.该部队士兵分为两路,第一 ...

  8. nyist 61 传纸条 nyist 712 探 寻 宝 藏(双线程dp问题)

    http://acm.nyist.net/JudgeOnline/problem.php?pid=61 http://acm.nyist.net/JudgeOnline/problem.php?pid ...

  9. 传纸条(一)(双线程dp)

    传纸条(一) 时间限制:2000 ms  |  内存限制:65535 KB 难度:5   描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行 ...

随机推荐

  1. WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于WS-MEX的实现](提供模拟程序)

    原文:WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于WS-MEX的实现](提供模拟程序) 通过<如何将一个服务发布成WSDL[编程篇]>的介绍我们知道了如何可以通过编程或者配 ...

  2. JAVA之等号、传类对象参数与c++的区别

    在JAVA中用等号对类对象进行赋值,实际上操作的是对象的地址. eg: package MyText; class ClassA { int value; public void seta(int v ...

  3. .bat脚本将windows server 2008设置成ntp时间同步服务器

    @echo off echo autor OAK @echo off echo -------------------------------- @echo off REG ADD HKEY_LOCA ...

  4. 重新签名apk文件(手工用命令行)

    re-sign.jar中后自动去除签名这个方法,经试验不可用! 1.去除准备重新签名SinaVoice.apk软件本身的签名 将apk文件后缀改为.zip,然后从winrar中删除META-INF文件 ...

  5. c语言:union,大小端

    union: 不允许只用联合变量名作赋值或其它操作. 也不允许对联合变量作初始化赋值,赋值只能在程序中进行. 小端存储: 以字节为单位,低存低,高存高. 任何数据在内存中都是以二进制(1或着0)顺序存 ...

  6. Ural1109_Conference(二分图最大匹配/匈牙利算法/网络最大流)

    解题报告 二分图第一题. 题目描写叙述: 为了參加即将召开的会议,A国派出M位代表,B国派出N位代表,(N,M<=1000) 会议召开前,选出K队代表,每对代表必须一个是A国的,一个是B国的; ...

  7. Principle of Computing (Python)学习笔记(5) BFS Searching + Zombie Apocalypse

    1 Generators   Generator和list comprehension非常类似 Generators are a kind of iterator that are defined l ...

  8. PHP学习之-1.6 PHP语句结束符

    PHP语句结束符 是不是我们在javascript,Java 的每一句代码结束的地方都有一个分号 ";" PHP的结束符号也是 ";". 注意:在PHP编程中需 ...

  9. 【实战】静默安装-oracle 11.2.0.3 on centos 5.10

    发现网上静默安装的文章非常多,乱七八糟,五花八门!来个扫盲的!   centos 5.10 下安装oracle 11g_r2 ************************************* ...

  10. shakes hands

    Description On February, 30th n students came in the Center for Training Olympiad Programmers (CTOP) ...