POJ 1952 BUY LOW,BUY LOWER
題目描述:
題目鏈接:POJ 1952 BUY LOW,BUY LOWER
題目大意:
題目背景是股市,要求在給定的價格序列中求每次購買價格都下降的最長的購買次數以及購買方案數。即求最長遞減子序列的長度,已經相同長度序列的個數。
解題思路:
第i項爲當前比較項,第j項是i項之前的某一項。
若滿足
prices[i]<prices[j] , 則maxlen[i] 的值滿足狀態轉移方程:
maxlen[i]=max(maxlen[i],maxlen[j]+1) 同時,最長遞減子序列的個數
maxnum[i] ,
- 在
maxlen[j]+1>maxlen[i] 時,maxnum[i]=max[j] ;- 在
maxlen[j]+1==maxlen[i] 時,maxnum[i]+=maxnum[j] ;特別的當
prices[i]==prices[j] 時,爲防止重複計數跳出循環。同時當maxlen[i]==1 時,即當前重複的數字並沒有對最大鏈長做出貢獻,故將maxnum[i] 置爲0 。
複雜度分析(最近正在學,有錯請指出):
時間複雜度
空間複雜度
AC代碼:
#include <cstdio>
#include <iostream>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 5100;
int prices[maxn];
int maxlen[maxn];
int maxnum[maxn];
int main(){
int N;
while(scanf("%d",&N) != EOF){
for(int i = 0; i < N; i++){
scanf("%d" ,&prices[i]);
maxlen[i] = 1;
maxnum[i] = 1;
}
for(int i = 1; i < N; i++)
for(int j = i - 1; j >= 0; j--){
if(prices[i] < prices[j]){
if(maxlen[j] + 1 > maxlen[i]){
maxlen[i] = maxlen[j] + 1;
maxnum[i] = maxnum[j];
}
else if(maxlen[i] == maxlen[j] + 1){
maxnum[i] += maxnum[j];
}
}
else if(prices[i] == prices[j]){
if(maxlen[i] == 1) maxnum[i] = 0;
break;
}
}
int anslen = 0,ansnum = 0;
for(int i = 0; i < N; i++)
if(maxlen[i] > anslen) anslen = maxlen[i];
for(int i = 0; i < N; i++)
if(maxlen[i] == anslen) ansnum += maxnum[i];
printf("%d %d\n", anslen, ansnum);
}
return 0;
}