P1108 低价购买 dp

  

题目描述

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

这里是某支股票的价格清单:

日期 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8, 9 ,10 ,11, 121,2,3,4,5,6,7,8,9,10,11,12

价格68 ,69 ,54, 64,68 ,64 ,70 ,67 ,78 ,62, 98, 8768,69,54,64,68,64,70,67,78,62,98,87

最优秀的投资者可以购买最多44次股票,可行方案中的一种是:

日期 2 , 5 , 6 ,102,5,6,10

价格 69, 68 ,64 ,6269,68,64,62

输入输出格式

输入格式:

第1行: N(1 \le N \le 5000)N(1≤N≤5000),股票发行天数

第2行: NN个数,是每天的股票价格。

输出格式:

两个数:
最大购买次数和拥有最大购买次数的方案数(\le 2^{31}≤231)当二种方案“看起来一样”时(就是说它们构成的价格队列一样的时候),这22种方案被认为是相同的。

输入输出样例

输入样例#1: 复制

12
68 69 54 64 68 64 70 67 78 62 98 87

输出样例#1: 复制

4 2

第一问是最长下降子序列的长度   第二问是最长长度的序列数

先过一遍n2 dp   然后在所得dp上进行一次dp求数量

注意是将f[i]=0

#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3f
const int N=100000+5;
int dp[N];
int f[N];
int a[N];
int main()
{
    int n;RI(n);
    rep(i,1,n)
    RI(a[i]);

    int maxx=0;
    rep(i,1,n)
    {
        dp[i]=1;
        rep(j,1,i-1)
        if(a[i]<a[j])
            dp[i]=max(dp[i],dp[j]+1);

        maxx=max(maxx,dp[i]);
    }
    int cnt=0;
    rep(i,1,n)
    {
        if(dp[i]==1)f[i]=1;
        rep(j,1,i-1)
        {
            if(dp[j]+1==dp[i]&&a[j]>a[i])
            f[i]+=f[j];
            else if(dp[i]==dp[j]&&a[i]==a[j])
            f[i]=0;
        }

        if(dp[i]==maxx)cnt+=f[i];
    }
    cout<<maxx<<" "<<cnt;

    return 0;
}

该方法给人觉得更好理解

#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3f
const int N=100000+5;
int dp[N];
int f[N];
int a[N];
int main()
{
    int n;RI(n);
    rep(i,1,n)
    RI(a[i]);

    int maxx=0;
    rep(i,1,n)
    {
        dp[i]=1;
        rep(j,1,i-1)
        if(a[i]<a[j])
            dp[i]=max(dp[i],dp[j]+1);

        maxx=max(maxx,dp[i]);

        rep(j,1,i-1)
        {
            if(dp[j]+1==dp[i]&&a[j]>a[i])
            f[i]+=f[j];
            else if(dp[i]==dp[j]&&a[i]==a[j])
            f[j]=0;
        }
        if(!f[i])
        f[i]=1;
    }
    int cnt=0;
    rep(i,1,n)
    if(dp[i]==maxx)
        cnt+=f[i];
    cout<<maxx<<" "<<cnt;

    return 0;
}



原文地址:https://www.cnblogs.com/bxd123/p/10863800.html

时间: 2024-07-31 01:08:55

P1108 低价购买 dp的相关文章

洛谷P1108 低价购买[DP | LIS方案数]

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

Luogu P1108 低价购买 DP

第一问求最长下降子序列,不提: 第二问:借鉴了最短路的方法??? 我们求出来了每个位置的最长下降子序列的长度,那么刻意这样这样转移 if f[i]==f[j]+1&&a[i]<a[j](i>j) 这代表f[i]可以由f[j]转移过来,所以 f[i]+=f[j] 但是会重复,所以当f[i]==f[j]&&a[i]==a[j]  时,说明没有发生任何转移,去掉一个. 初值 当f[i]==1时,c[i]=1; #include<iostream> #inc

luogu P1108 低价购买

题目链接 luogu P1108 低价购买 题解 朴素n^2dp,对于方案的转移利用加法原理,dp每一种最有解的方案 代码 #include<iostream> #include<cstdio> #include<algorithm> #include<cmath> using namespace std; const int maxn = 60007; int f[maxn],c[maxn],a[maxn]; int cnt=0; int n; int m

入门动态规划 洛谷P1108 低价购买

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

低价购买 dp

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

P1108 低价购买

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

题解 P1108 【低价购买】

题目链接 Solution 低价购买 题目大意:求一个数列的最长下降子序列长度,以及长度最长的下降子序列的数量 题目分析:求最长下降子序列是常规操作了,可以直接用朴素\(O(n ^ 2)\)算法,也可以用二分做到\(O(nlogn)\)复杂度,不过\(n \leq 5000\)朴素算法随便跑 那么如何统计方案呢? 我们\(dp\)求最长下降子序列是设\(d(i)\)表示以\(i\)结尾的下降子序列的最长长度.同理,我们可以用\(f(i)\)表示以\(i\)结尾,长度为\(d(i)\)的下降子序列

低价购买-最长下降子序列和方案计数

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

低价购买 (动态规划,变种最长下降子序列(LIS))

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