標籤:des style java color os io 資料 for
低價購買Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)Total Submission(s) : 19 Accepted Submission(s) : 4Font: Times New Roman | Verdana | GeorgiaFont Size: ← →Problem Description“低價購買”這條建議是在股票市場取得成功的一半規則。要想被認為是偉大的投資者,你必須遵循如下的購買建議:“低價購買,再低價購買”。每次你購買一支股票,你必須用低於你上次購買它的價格購買它。買的次數越多越好!你的目標是在遵循以上建議的前提下,求你最多能購買股票的次數。你將被給出一段時間內一支股票每天的出售價(2^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
最優秀的投資者可以購買最多4次股票,可行方案中的一種是:
日期 2 5 6 10
價格 69 68 64 62Input輸入有多組資料,每組資料有兩行,第1行:N(1<=N<=5000),股票的發行天數;
第2行:N個數,是每天的股票價格。
Output對於每組輸入輸出僅一行,包含兩個數:最大購買次數和擁有最大購買次數的方案數(<=2^31),當兩種方案“看起來一樣”(也就是說它們構成的價格隊列一樣的時候),這兩種方案被認為是相同的。Sample Input
1268 69 54 70 68 64 70 67 78 62 98 87
Sample Output
4 4
//最難的就是要求出方案數,用num[i]表示到第i個數的最長下降子序列有幾種方案數。在掃描[1,i-1]尋找最優解,如果當前解與已知解相同就進行累加,第二重迴圈j應該從i-1到1逆序迴圈因為越靠近最優解的會有不少於靠前的方案數。
#include<cstdio>#include<cstring>int price[5001],num[5001],dp[5001];int main(){ int n,i,j,t; while(scanf("%d",&n)!=EOF) { memset(dp,0,sizeof(dp)); memset(num,0,sizeof(num)); memset(price,0,sizeof(price)); for(i=0;i<n;i++) scanf("%d",&price[i]); for(i=0;i<=n;i++) { t=1<<30; num[i]=1; for(j=i-1;j>=0;j--) { if(price[j]>price[i]) { if(dp[j]>=dp[i]) { t=price[j]; dp[i]=dp[j]+1; num[i]=num[j]; //同一最長下降只序列方案數相同 } else if(dp[j]+1==dp[i]&&price[j]<t) //保證是最長下降子序列並且不會重複 { t=price[j]; num[i]+=num[j]; } } } } printf("%d %d\n",dp[n],num[n]); } return 0;}