P1020 导弹拦截

做~自己de王妃 提交于 2019-11-27 03:39:43

P1020 导弹拦截

思路:

首先想到的转移方程就是:
dp[i]=max(dp[j]j=i)+1dp[i] = max(dp[j]_{j=高度大于i})+1
就是说当考虑第i个导弹的状态时,应当是从前面所有比它高的导弹中取值最大的+1,
emmm O(n2)O(n^2)吧,但是第二题就不会了,难道要我重复求,直到求完?看了题解才知道(膜题解大佬)第二题是求最长上升序列长度,这个也好办,至于维护最长,最短序列什么的,我是没看懂和dp有什么关系,果断不做.

code

#include <algorithm>
#include <bits/stdc++.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
const int maxn = 1005;
int missle[100000+5];
int dp[50000+5];
int main() 
{
#ifdef LOCAL
    freopen("C:\\Users\\hsxny\\Desktop\\in.txt", "r", stdin);
#endif
int iter = 0;
while(scanf("%d",&missle[iter++])!=EOF);
int M = iter-1;
int ans = 0;
for(int i=0;i<M;i++)
{
    int temp = 0;
    for(int j=0;j<i;j++)
    {
        if(missle[j]>=missle[i])
        temp = max(temp, dp[j]);
    }
    dp[i] = temp+1;
    ans = max(ans, dp[i]);
}
int ans2 = 0;
for(int i=0;i<M;i++){
        dp[i]=1;//以第i个数结尾的最长上升子序列的长度至少为1(当这个序列只有它本身这一个数) 
        for(int j=1;j<i;j++){
            if(missle[j]<missle[i])
                dp[i]=max(dp[i],dp[j]+1);
        }
        ans2=max(ans2,dp[i]);//更新ans2 
    }
printf("%d\n%d\n", ans, ans2);
return 0;
}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!