题目:免费午餐

题目描述

为了增加顾客,Sally的店铺决定提供免费午餐,顿时门庭若市,但是不久Sally的原材料不足了….因此Sally决定公布一项决定:凡是来本店吃免费午餐的,一天吃能吃一次,吃的数量必须比上一次吃的少, 点的必须在上一次后面,且免费午餐将只有N个种类任君选择,为了能吃到最多的免费午餐,你将如何安排每日吃的数量呢?

输入格式

第一行一个数N,表示免费午餐的种类(0<=N<=100000)
第二行N个数,表示每个免费午餐的数量(0<=数量<=100000)

输出格式

一个数,表示最多能吃多少天.

分析:

典型的DP,但朴素的DP已不能满足该题的数据,因此就用到了刚才写的求最大不降序列算法了,只需小小的改动即可。

该题数据十分阴险,竟有数据等于0的情况,需注意。

代码实现:—————————————————————————————————————————————————

#include<iostream>
using namespace std;

int a[100001],c[100001];

int find(int len,int n){
    int left=1,right=len,mid;
    while(left<=right)
    {
     mid=(left+right)/2;
     if(c[mid]==n) return mid;
     else if(c[mid]>n) left=mid+1;
     else if(c[mid]<n) right=mid-1;
                      }
     return left;
    }

int main()
{
    int n,i,j,k,len;bool p=1;
    cin>>n;   if(n==0) {cout<<0;return 0;}
    for(i=1;i<=n;i++)
    {cin>>a[i];if(a[i]!=0) p=0;}
   
    if(p==1) {cout<<0;return 0;}
   
    c[1]=a[1];
    len=1;
   
    for(i=1;i<=n;i++)
    {
     if(a[i]==0) continue;
     j=find(len,a[i]);
     c[j]=a[i];
     if(j>len)
     len=j;          
                     }
   
    cout<<len;
    system("pause");
    return 0;
    }

原文地址:https://www.cnblogs.com/noip/p/2291261.html