• HDU 1257 最少拦截系统 dp + 贪心


    http://acm.hdu.edu.cn/showproblem.php?pid=1257

    一开始的时候还用了单调栈维护,toNext[i] 表示第i个往右边,第一个比它小的数。

    我还以为一路这样弄下去就搞定了。

    但是有数据卡我了。

    6 5 6 5 4 3 2 1 5 4 3 2 1

    这样其实只需要两个。但是我的做法会输出3个。。

    正解是一个简单的dp

    dp[i]表示第i个导弹拦截的最小高度。

    然后用一个ans记录一共用了多少枚导弹

    每有一个新的值,就优先找一枚合法的导弹放进去就行了。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    const int maxn = 30000 + 20;
    int dp[maxn];
    int n;
    void work() {
    //    memset(dp, 0x3f, sizeof dp);
        int ans = 0;
        for (int i = 1; i <= n; ++i) {
            int a;
            scanf("%d", &a);
            int j;
            for (j = 1; j <= ans; ++j) {
                if (dp[j] >= a) {
                    dp[j] = a;
                    break;
                }
            }
            if (j == ans + 1) dp[++ans] = a;
        }
        cout << ans << endl;
    }
    
    int main() {
    #ifdef local
        freopen("data.txt","r",stdin);
    #endif
        while (scanf("%d", &n) != EOF) work();
        return 0;
    }
    View Code

    这题还有另外一个做法。

    采用逆向思维,现在它是要分成若干个最长不升子序列。

    那么相反的就是最长上升子序列。输出长度即可。

    为什么呢?

    因为最长上升子序列,都是选取一些尽可能小的点组合成的,而这些点,刚好就是没得下降的点啦。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    const int maxn = 30000 + 20;
    int dp[maxn];
    int a[maxn];
    int n;
    void work() {
        int lendp = 0;
        for (int i = 1; i <= n; ++i) cin >> a[i];
        dp[++lendp] = a[1];
        for (int i = 2; i <= n; ++i) {
            if (a[i] > dp[lendp]) {
                dp[++lendp] = a[i];
            } else {
                int pos = lower_bound(dp + 1, dp + 1 + lendp, a[i]) - dp;
                dp[pos] = a[i];
            }
        }
        cout << lendp << endl;
    }
    
    int main() {
    #ifdef local
        freopen("data.txt","r",stdin);
    #endif
        while (cin >> n) work();
        return 0;
    }
    View Code
  • 相关阅读:
    [转载]c++转python
    [转载]One-hot编码
    [转载]各种机器学习算法的应用场景
    SVC和SVR
    机器学习-正则化+回归与分类辨析
    C#编译时,提示缺少NuGet包
    C++中 左值和右值的区别
    C++11并发编程实战 免费书籍
    静态库和动态库
    C++中string类
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6005211.html
Copyright © 2020-2023  润新知