拦截导弹 (加了神奇的位运算)

  

  传送门 :洛谷 P1020 导弹拦截

 

 思路 : 第一问为求一段序列 的最长不下降子序列的长度 

第二问求得是 不下降子序列的个数

对于第一问,跑一边 最长不下降子序列即可

对于第二问, 依旧是跑一边第一问即可 (雾)

其实还要加一点神奇的位运算。。

 

#include <iostream>
#include <cstdio>
#include <cstring>
#define Max 1000
using namespace std;
int N, M;
int heigh [Max], dp_1[Max], dp_2 [Max];
int dp [Max];
int Max_Answer , Total = 1;
int Make (int dp [], bool flag)
{
    for (int i = 2; i < Total; i++)
        for (int j = 1; j < i; j++)
            if (flag ^ (heigh [j] >= heigh [i]))  //在这里运用了神奇的位运算,相当于一个开关, 去掉后是一个裸的跑最长不下降子序列
                dp [i] = max (dp [i], dp [j] + 1); 
    int Maxn = 1;
    for (int i = 1; i <= Total; i++)
        Maxn = max (Maxn, dp [i]);  // 找出最大值 
    return Maxn;
}
int main()
{
    ios :: sync_with_stdio (false);
    int x;
    while (cin >> heigh [Total++])
    {
        dp_1 [Total - 1] = 1;       // 初始化为 每个数 之前最长不下降序列的最大长度 和 它之前 不下降序列的个数为 1 
        dp_2 [Total - 1] = 1;
    }
    Total--;
    cout << Make (dp_1, 0) << endl; 
    cout << Make (dp_2, 1) << endl;
    return 0;
}

 

posted @ 2016-11-16 15:30  ZlycerQan  阅读(217)  评论(0编辑  收藏  举报