zoukankan      html  css  js  c++  java
  • 洛谷 P1108 低价购买

    P1108 低价购买
    标签 动态规划
    难度 提高+/省选-
    题目描述
    “低价购买”这条建议是在奶牛股票市场取得成功的一半规则。要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买;再低价购买”。每次你购买一支股票,你必须用低于你上次购买它的价格购买它。买的次数越多越好!你的目标是在遵循以上建议的前提下,求你最多能购买股票的次数。你将被给出一段时间内一支股票每天的出售价(2^16范围内的正整数),你可以选择在哪些天购买这支股票。每次购买都必须遵循“低价购买;再低价购买”的原则。写一个程序计算最大购买次数。
    这里是某支股票的价格清单:
    日期 1 2 3 4 5 6 7 8 9 10 11 12
    价格 68 69 54 64 68 64 70 67 78 62 98 87
    最优秀的投资者可以购买最多4次股票,可行方案中的一种是:
    日期 2 5 6 10
    价格 69 68 64 62
    输入输出格式
    输入格式:
    第1行: N (1 <= N <= 5000),股票发行天数
    第2行: N个数,是每天的股票价格。
    输出格式:
    输出文件仅一行包含两个数:最大购买次数和拥有最大购买次数的方案数(<=2^31)当二种方案“看起来一样”时(就是说它们构成的价格队列一样的时候),这2种方案被认为是相同的。
    输入输出样例
    输入样例#1:
    BUYLOW.IN
    12
    68 69 54 64 68 64 70 67 78 62 98 87
    输出样例#1:
    BUYLOW.OUT
    4 2

    /*
    第一问是裸的最长下降子序列问题.
    第二问求最长下降子序列的构造方案数.
    s[i].tot表示到i的最长上升子序列长度.
    s[i].x表示到i的最长上升子序列的方案数.
    eg:4 2 2 1. 
    最长是两个4 2 1 但是这种方案只能统计一次.
    显然后边的比前边的更优.
    这种情况下为了避免重复计算.
    我们把前面的s[].x设为0.
    如果s[i].tot==s[j].tot+1&&a[j]>a[i](j<i)
    即i是j序列的延续我们由计数原理计算s[i].x+=s[j].x.
    最后只需要计算合法的子序列尾部的方案数就可以了. 
    */
    #include<iostream>
    #include<cstdio>
    #define MAXN 5001
    using namespace std;
    int a[MAXN],n,ans,tot;
    struct data{int tot,x;}s[MAXN];
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++)
          a[i]=read();
        for(int i=1;i<=n;i++)
        {
            s[i].tot=1;
            for(int j=1;j<=i-1;j++)
              if(a[i]<a[j])
                s[i].tot=max(s[i].tot,s[j].tot+1);
            if(s[i].tot==1) s[i].x=1;
            for(int j=1;j<=i-1;j++)
              if (s[i].tot==s[j].tot+1&&a[j]>a[i]) s[i].x+=s[j].x; 
              else if(a[j]==a[i]&&s[i].tot==s[j].tot) s[j].x=0; 
            ans=max(ans,s[i].tot);
        }
        for(int i=1;i<=n;i++)
          if(ans==s[i].tot) tot+=s[i].x;
        printf("%d %d",ans,tot);
        return 0;
    }
  • 相关阅读:
    游戏 猜拳游戏
    python的变量 以及操作系统
    python的异常处理
    python 三元运算
    python random 的用法
    python基础
    Round #417 A. Sagheer and Crossroads(Div.2)
    Round #416 B. Vladik and Complicated Book(Div.2)
    Round #416 A. Vladik and Courtesy(Div.2)
    Educational Round 26 D. Round Subset
  • 原文地址:https://www.cnblogs.com/nancheng58/p/6070758.html
Copyright © 2011-2022 走看看