usaco training 4.3.1 Buy Low, Buy Lower 题解

来源:互联网 发布:淘宝开店运营教程视频 编辑:程序博客网 时间:2024/04/27 22:04

       

Buy Low, Buy Lower题解

The advice to "buy low" is half the formula to success in the stock market. But to be considered a great investor you must also follow this problems' advice:

"Buy low, buy lower"

That is, each time you buy a stock, you must purchase more at a lower price than the previous time you bought it. The more times you buy at a lower price than before, the better! Your goal is to see how many times you can continue purchasing at ever lower prices.

You will be given the daily selling prices of a stock over a period of time. You can choose to buy stock on any of the days. Each time you choose to buy, the price must be lower than the previous time you bought stock. Write a program which identifies which days you should buy stock in order to maximize the number of times you buy.

By way of example, suppose on successive days stock is selling like this:

 Day   1  2  3  4  5  6  7  8  9 10 11 12Price 68 69 54 64 68 64 70 67 78 62 98 87

In the example above, the best investor (by this problem, anyway) can buy at most four times if they purchase at a lower price each time. One four day sequence (there might be others) of acceptable buys is:

Day    2  5  6 10Price 69 68 64 62

PROGRAM NAME: buylow

INPUT FORMAT

Line 1:N (1 <= N <= 5000), the number of days for which stock prices are available.Line 2..etc:A series of N positive space-separated integers (which may require more than one line of data) that tell the price for that day. The integers will fit into 32 bits quite nicely.

SAMPLE INPUT (file buylow.in)

1268 69 54 64 68 64 70 6778 62 98 87

OUTPUT FORMAT

Two integers on a single line:

  • the length of the longest sequence of decreasing prices
  • the number of sequences that have this length

In counting the number of solutions, two potential solutions are considered the same (and would only count as one solution) if they repeat the same string of decreasing prices, that is, if they "look the same" when the successive prices are compared. Thus, two different sequence of "buy" days could produce the same string of decreasing prices and be counted as only a single solution.

SAMPLE OUTPUT (file buylow.out)

4 2

描述

“逢低吸纳”是炒股的一条成功秘诀。如果你想成为一个成功的投资者,就要遵守这条秘诀:

"逢低吸纳,越低越买"

这句话的意思是:每次你购买股票时的股价一定要比你上次购买时的股价低.按照这个规则购买股票的次数越多越好,看看你最多能按这个规则买几次。

给定连续的N天中每天的股价。你可以在任何一天购买一次股票,但是购买时的股价一定要比你上次购买时的股价低。写一个程序,求出最多能买几次股票。

以下面这个表为例, 某几天的股价是:

天数 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

[编辑]格式

PROGRAM NAME: buylow

INPUT FORMAT:

(file buylow.in)

第1行: N (1 <= N <= 5000), 表示能买股票的天数。

第2行以下: N个正整数 (可能分多行) ,第i个正整数表示第i天的股价. 这些正整数大小不会超过longint(pascal)/long(c++).

OUTPUT FORMAT:

(file buylow.out)

只有一行,输出两个整数:

能够买进股票的天数和长度达到这个值的股票购买方案数量

在计算方案的数量的时候,如果两个方案的股价序列相同,那么这样的两个方案被认为是相同的(只能算做一个方案)。因此,两个不同的天数序列可能产生同一个股价序列,这样只能计算一次。

[编辑]SAMPLE INPUT

1268 69 54 64 68 64 70 6778 62 98 87

[编辑]SAMPLE OUTPUT

4 2


这道题以前2002年的月赛里做过,只是意外地发现USACO里的知识介绍是BIG NUMBER,即高精度算法。于是匆匆加了个高精。上次1047的告警最小公倍数已经让我的高精炉火纯青O(∩_∩)O~~

代码:

/*PROG:buylowID:juan1973LANG:C++*/#include<stdio.h>#include<cstring>using namespace std;const int maxn=5001;struct arr{  int num;  int p[101];}cnt[maxn],ans2;long long  a[maxn],f[maxn];bool flag[20*maxn];int n,i,j,ans;arr add(arr a,arr b){  a.num=b.num>a.num?b.num:a.num;int x=0;  for (int i=1;i<=a.num;i++)  {    a.p[i]=a.p[i]+b.p[i]+x;x=a.p[i]/10;a.p[i]%=10;  }  if (x>0) {a.num++;a.p[a.num]=x;}  return a;}int main(){  freopen("buylow.in","r",stdin);  freopen("buylow.out","w",stdout);  scanf("%ld",&n);  for (i=1;i<=n;i++) scanf("%ld",&a[i]);  for (i=1;i<=n;i++)  {    f[i]=1;    for (j=1;j<i;j++)      if (a[j]>a[i]&&f[j]+1>f[i]) f[i]=f[j]+1;    ans=f[i]>ans?f[i]:ans;    memset(flag,0,sizeof(flag));    for (j=i-1;j>0;j--)      if (f[j]+1==f[i]&&a[j]>a[i]&&!flag[a[j]])       {        flag[a[j]]=true;        cnt[i]=add(cnt[i],cnt[j]);      }    if (cnt[i].num==0&&cnt[i].p[1]==0) {cnt[i].num=1;cnt[i].p[1]=1;}  }  memset(flag,0,sizeof(flag));  for (i=n;i>0;i--)    if (f[i]==ans&&!flag[a[i]])     {      flag[a[i]]=true;      ans2=add(ans2,cnt[i]);    }  printf("%ld ",ans);  for (i=ans2.num;i>1;i--) printf("%ld",ans2.p[i]);printf("%ld\n",ans2.p[1]);  //scanf("%ld",n);  return 0;}

0 0
原创粉丝点击