Fork me on GitHub

P1020 导弹拦截(弱数据)

https://www.luogu.org/problem/show?pid=1020
这里写图片描述

法一,dp
第一问要求一个以第一个为起点最长不上升子序列。
第二问,只要后面的比前一个高,就要再另用一套系统,所以问题可以转化为求最长的上升子序列。

#include<iostream>
#include<cstdio>
#define LL long long
#define M 30010
using namespace std;
int a[111],n=0;
int d[111],f[111];
int main()
{
    for(;scanf("%d",&a[++n])==1;)
    {
        d[n]=1;
    }
    d[0]=1;
    for(int i=2;i<=n;i++)
    {
        int maxn=0;
        for(int j=1;j<=i-1;j++)
         if(a[j]>=a[i]&&maxn<d[j])
          maxn=d[j];
        d[i]+=maxn;
    }
    printf("%d\n",d[n]);

    for(int i=0;i<=n;i++) d[i]=1;
    for(int i=2;i<=n;i++)
    {
        int maxn=0;
        for(int j=1;j<=i-1;j++)
         if(a[j]<a[i]&&maxn<d[j])
          maxn=d[j];
        d[i]+=maxn;
    }
    int maxn=0;
    for(int i=1;i<=n;i++)
    {
        maxn=max(maxn,d[i]);
    }
    printf("%d",maxn);
    return 0;
} 

法二、贪心
每次打炮弹时,都在已有系统中找一个满足条件的最低的系统,如果没有满足条件的,那么就需要加一套系统。

#include<iostream>
#include<cstdio>
#include<algorithm>
#define LL long long
#define M 31000
using namespace std;
int a[111],n=0;
int d[111],h[111];
void dfs(int x,int m)
{
    if(x==n+1) 
    {
        printf("%d\n",m);
        return;
    }
    int minn=M+1,minj;
    for(int i=1;i<=m;i++)
    {
        if(h[i]>a[x]&&h[i]<minn)
         minn=h[i],minj=i;
    }
    if(minn==M+1) 
    {
        h[m+1]=a[x];
        dfs(x+1,m+1);
    }
    else
    {
        h[minj]=a[x];
        dfs(x+1,m);
    }
    return;
} 
int main()
{
    for(;scanf("%d",&a[++n])==1;)
    {
        d[n]=1;
    }
    d[0]=1;
    for(int i=2;i<=n;i++)
    {
        int maxn=0;
        for(int j=1;j<=i-1;j++)
         if(a[j]>=a[i]&&maxn<d[j])
          maxn=d[j];
        d[i]+=maxn;
    }
    printf("%d\n",d[n]);
    h[1]=M;
    dfs(1,1);
    return 0;
} 
posted @ 2017-09-24 17:48  primes  阅读(97)  评论(0编辑  收藏  举报