zoukankan      html  css  js  c++  java
  • [wikioi]拦截导弹

    http://wikioi.com/problem/1044/

    这道题是DP。前一问很自然可以规约成最长不升(含等号下降)子序列。难点在后一问为何能规约成最长上升子序列。后来看了网上的回答,仍然没有简单的理解方法,似乎需要证明。证明可以这么来看,一是如果有长度为n的上升子序列,那么至少要n个序列;二,可以找一个方法构造出这n个队列。(方法暂不表)


    但如果用贪心,就好理解多了。
    比如:389 207 155 300 299 170 158 65
    贪心就是从头往后,只要能放入第一个队列就第一个,那么389,207,155,然后跳过一些放入65
    然后第二个队列开始300。最终是300,299,170,158。

    不过这里的代码仍然是很俗的两个DP。

    #include <iostream>
    #include <cstring>
    using namespace std;
    
    int a[25];
    int down[25];
    int up[25];
    int main()
    {
        int n = 0;
        memset(a, 0, sizeof(a));
        memset(down, 0, sizeof(down));
        memset(up, 0, sizeof(up));
        while (cin >> a[n])
        {
            n++;
        }
        down[0] = 1;
        up[0] = 1;
        for (int i = 1; i < n; i++)
        {
            int dmax = 1;
            int umax = 1;
            for (int j = 0; j < i; j++)
            {
                if (a[j] >= a[i] && dmax < down[j]+1)
                {
                    dmax = down[j]+1;
                }
                if (a[j] < a[i] && umax < up[j]+1)
                {
                    umax = up[j]+1;
                }
            }
            down[i] = dmax;
            up[i] = umax;
        }
        int max = 0;
        for (int i = 0; i < n; i++)
        {
            if (max < down[i]) max = down[i];
        }
        cout << max << endl;
        max = 0;
        for (int i = 0; i < n; i++)
        {
            if (max < up[i]) max = up[i];
        }
        cout << max << endl;
        return 0;
    }
    

      

  • 相关阅读:
    eg_5
    浅谈Java中的Hashmap
    java中方法传入参数时:值传递还是址传递?
    重温概率学(一)期望、均值、标准差、方差
    博客搬家
    golang sync/atomic
    单机配置kafka和zookeeper
    异步消息队列组件
    2017总结
    看完轻松年薪30w+
  • 原文地址:https://www.cnblogs.com/lautsie/p/3337600.html
Copyright © 2011-2022 走看看