题目:免费午餐
题目描述
为了增加顾客,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;
}