(洛谷 1108)低价购买

来源:互联网 发布:centos7 软件管理器 编辑:程序博客网 时间:2024/05/22 00:30

题目描述

“低价购买”这条建议是在奶牛股票市场取得成功的一半规则。要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买;再低价购买”。每次你购买一支股票,你必须用低于你上次购买它的价格购买它。买的次数越多越好!你的目标是在遵循以上建议的前提下,求你最多能购买股票的次数。你将被给出一段时间内一支股票每天的出售价(2^16范围内的正整数),你可以选择在哪些天购买这支股票。每次购买都必须遵循“低价购买;再低价购买”的原则。写一个程序计算最大购买次数。

分析:轻而易举的知道求最长下降子序列,但是方案就难了些。

状态转移方程:如果a[j]>a[i] f[i]=max(f[j]+1,f[i])

#include <cstdio>
#include <algorithm>
#include <cstring>
#define go(a,b,c) for (int a=b;a<=c;a++)
using namespace std;
int n,big=1,ans,a[5010],f[5010],b[5010];
int main(){
    scanf("%d",&n); f[1]=1; b[1]=1;
    go(i,1,n) scanf("%d",&a[i]);
    go(i,2,n){f[i]=1;
    go(j,1,i-1) if (a[j]>a[i]) f[i]=max(f[j]+1,f[i]);//最长下降子序列
    if (f[i]==1) b[i]=1; //火车头当然是只有1种方案。
    go(j,1,i-1) if (a[j]>a[i]&&f[i]==f[j]+1) b[i]+=b[j];//如果出现走法加上前一个的方案
    else if (a[j]==a[i]&&f[i]==f[j]) b[j]=0; big=max(big,f[i]);//覆盖,当然要后面的(后面的前途无量
    } 
    for (int i=1;i<=n;i++)
    if (big==f[i]) ans+=b[i]; //最大值的方案和
    printf("%d %d",big,ans);
}

原创粉丝点击