zoukankan      html  css  js  c++  java
  • poj 1952 buy low buy lower(DP)

    描述 Description

    “低买高卖”是在神牛证券市场上成功的秘诀的一半。作为一个好的投资者,你必须还遵守下面这条建议:

    “逢低吸纳,越低越买”

    每次你购买股票的时候,你必须以比上次购买这只股票的价格更低的价格来购买这只股票。购买比上次便宜的股票的次数越多越好!你的目标是计算像这样的低价进仓最多可以进行多少次。

    数据会给你一只股票在一段时期内每日的交易价格(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

    一个最好的投资者(至少在这个问题里是这样)可以最多以比上一次的价格更低的价格购买四次股票。一种可行的购买方案是(当然,也有其他的购买方案):

    日期 2   5   6   10
    价格 69 68 64 62

    输入 Input

    ※ 第一行:N(1 ≤ N ≤ 5,000),给定股价的天数。
    ※ 第二、三行及后面:一个有 N 个用空格隔开的整数的序列,除了最后一行比较少之外,每一行有十个数字。

    输出 Output

    在一行之内输出两个整数:
    ※ 最长的下降价格序列的长度
    ※ 有这样长度的下降序列的个数

    在序列个数的统计过程中,两个可能的解将会被判作相同(以及只计算一次),如果它们的序列是完全相同的两个串,也就是说,比较连续的价格的时候它们“看上去相同”。于是,两个不同的“购买日期”序列如果得到的是同一个“价格”序列,就应该被看作是一个解

    *思路:首先要确定最长下降子序列再就是记录最长下降子序列的个数(同样的最长子序列不可重复计数)单纯求最长子序列用dp很快就解决。难点在于求其个数与去重。以下数组time计算当前阶段最下降长子序列的个数

    #include<iostream>
    #include<cstring>
    #define num 5005
    using namespace std;
    int main()
    {
        int n,i,l=0,s=0,k,dp[num],a[num],time[num];
        cin>>n;
        for(i=1;i<=n;i++)
            cin>>a[i];
        for(i=1;i<=n;i++)
        {
            dp[i]=1;
            time[i]=1;//初始化
        }
        for(i=2;i<=n;i++)
            for(k=i-1;k>=1;k--)
            {
                if(a[k]>a[i])
                {
                    if(dp[i]<dp[k]+1)
                    {
                        dp[i]=dp[k]+1;
                        time[i]=time[k];//此时a[i]与其前面的数构成最长下降子序列,所以前面time[i]=time[k]
                    }
                    else if(dp[i]==dp[k]+1)
                        time[i]+=time[k];//此时到i时产生与前面最长下降子序列长度相同的子序列但是a[k]!=a[i],所以到i时最长下降子序列个数是新构成的(包括a[i])与旧的(没有a[i])数量的和。
                }
                else if(a[k]==a[i])
                {
                    if(dp[i]==1) time[i]=0;//假如碰到一个前面已经出现的数并且这个数的dp[i]==1说明他与前面相等的数之间并没有构成新的最长下降子序列,所以与前面的数等价,令其time[i]=0防止重复计数。例如:3 2 1 3 2 1此时两个3等价第二个3的dp值等于1,但是3 2 6 3 2中两个3不等价此时第二个3的dp值显然不等于1.
                   break;
                }
            }
        for(i=1;i<=n;i++)
            if(dp[i]>l)
                l=dp[i];
        for(i=1;i<=n;i++)
            if(dp[i]==l)
                s+=time[i];
        cout<<l<<' '<<s<<endl;
        return 0;
    }
    

      

  • 相关阅读:
    38) 收集centos所有版本镜像下载地址
    37) 查看linux 操作系统为多少位
    php面向对象高级应用一
    php form表单的验证+提交到数据库
    php获取form表单数据
    php form表单的提交
    php form表单概念
    php日期和时间的应用
    php日期和时间函数
    php字符串函数操作实例(2)
  • 原文地址:https://www.cnblogs.com/Neptunes/p/3262323.html
Copyright © 2011-2022 走看看