P1108 低价购买 dp
Posted bxd123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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种方案被认为是相同的。
输入输出样例
12 68 69 54 64 68 64 70 67 78 62 98 87
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; }
以上是关于P1108 低价购买 dp的主要内容,如果未能解决你的问题,请参考以下文章