Happy Birthday (最长上升(下降)子序列)

Today it’s February 13th. It’s a very special day: Miguel’s birthday! Like every year, he’s organised a
big celebration for all his friends. He prepared a succulent dinner at his house. Everyone had a lot of
fun and the celebration was a complete success.
Now it’s time for the not-so-funny cleaning up. He wants to start with moving all the dishes from
the table to the kitchen. Since he’s been going to the gym lately, he feels strong enough to pile and
carry at once as many dishes as he wants. Time doesn’t go unnoticed though: he’s not as agile as he
used to be, so he can only carry the stack of dishes if it’s completely stable. A stack of dishes is stable
if each dish on the stack is bigger or equal in size than all the dishes above it. If the stack wasn’t stable
he would drop the dishes and would have even more things to clean!
At the beginning of the scene, Miguel is empty-handed in one side of the table, walks along the
table finding and maybe collecting dishes of different sizes until he reaches the other side, and then
brings the collected dishes to the kitchen. When he finds a dish, he can:
• ignore the dish.
• if he has empty hands, pick up the dish.
• if he has a stack of dishes on his hands, pile the dish on top of the stack.
• if he has a stack of dishes on his hands, put the stack on top of the dish, then pick up the new
stack (including the dish).
Miguel is tired, so he wants to clean up the table as soon as possible. He’d like to take as many
dishes as he can in each run, but he’s exhausted from the party and can’t think clearly. He’s asked you
for help to find out what the maximum number of dishes he can collect in a single run is.
Input
Input contains several datasets. Each dataset consists on two lines. The first line of each dataset
contains an integer N (1 ≤ N ≤ 500), the number of dishes on the table. The second line of each
dataset contains N integers, k1 . . . kN (1 ≤ ki ≤ 1000), specifying the size of each dish he finds, in the
same order he finds them. Input ends with a dataset with N = 0. This case shouldn’t be processed.
Output
For each dataset, print the maximum number of dishes Miguel can collect in a single run.
Sample Input
6
3 1 5 6 2 4
6
3 4 2 5 2 6
0
Sample Output
4

6

题目大概:

给你n个数,你可以按顺序,从这数中,去取数,加到自己手中,自己手中的数,是排成了一个自上而下的堆,上面小,下面大,取得的数,只能放在最下方,或者最上方。问最多,这个堆有多大。

思路:

可以先求出,以每个数结尾的最长上升子序列和最长下降子序列。

然后枚举每两个数(一个上升结尾,一个下降结尾),是否是最长的。

代码:

#include <bits/stdc++.h>

using namespace std;
const int maxn=510;
int dp1[maxn];
int dp2[maxn];
int a[maxn];
int main()
{
    int n;
    while(~scanf("%d",&n)&&n)
    {
        memset(dp1,0,sizeof(dp1));
        memset(dp2,0,sizeof(dp2));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        //上升
        for(int i=1;i<=n;i++)dp1[i]=1;
        for(int i=n;i>=1;i--)
        {
            for(int j=n;j>i;j--)
            {
                if(a[j]>=a[i])
                {
                    if(dp1[i]<dp1[j]+1)
                    {
                        dp1[i]=dp1[j]+1;
                    }
                }
            }
        }
        //下降
        for(int i=1;i<=n;i++)dp2[i]=1;
        for(int i=n;i>=1;i--)
        {
            for(int j=n;j>i;j--)
            {
                if(a[j]<=a[i])
                {
                    if(dp2[i]<dp2[j]+1)
                    {
                        dp2[i]=dp2[j]+1;
                    }
                }
            }
        }
        int sum=0;
        for(int i=1;i<=n;i++)
        {
            sum=max(sum,max(dp1[i],dp2[i]));//自身
            for(int j=i+1;j<=n;j++)
            {
                if(a[i]<a[j])//大的上升,小的下降
                sum=max(sum,dp1[j]+dp2[i]);
                else if(a[i]>a[j])
                sum=max(sum,dp1[i]+dp2[j]);
            }
        }
        printf("%d\n",sum);

    }

    return 0;
}




猜你喜欢

转载自blog.csdn.net/a1046765624/article/details/80578867
今日推荐