洛谷-【動態規劃】- 大朋友的數字
阿新 • • 發佈:2019-01-24
在NOIP2013的賽場上,常神牛華麗麗的手殘了,小朋友的數字一題只得了10分。於是,他要惡搞一下這道題。
題目描述
有一批大朋友(年齡15歲以上),他們每人手上拿著一個數字,當然這個數字只有1位,也就是0到9之間。每個大朋友的分數為在他之前的最長不下降子序列中所有數之和。(這個序列必須以它作為結尾!)如有多個最長不下降子序列,那麼取編號字典序最小的。現在告訴你有n個大朋友,以及他們各自的數字,請你求出他們每個人的分數。
輸入輸出格式
輸入格式:
輸入檔案為bignum.in。
第一行,1個數n。
第二行,n個數,分別表示每個人的數字。
輸出格式:
輸出檔案為bignum.out。
一行,n個數,分別表示每個人的分數。
輸入輸出樣例
輸入樣例#1: 複製
【輸入輸出樣例1】
5
1 2 5 3 4
【輸入輸出樣例2】
5
1 7 5 9 6
輸出樣例#1: 複製
【輸入輸出樣例1】
1 3 8 6 10
【輸入輸出樣例2】
1 8 6 17 12
說明
【樣例解釋1】
五個人分數分別為(1),(1+2),(1+2+5),(1+2+3),(1+2+3+4).
【樣例解釋2】
五個人分數分別為(1),(1+7),(1+5),(1+7+9){還有一個(1,5,9)},(1+5+6)。
【資料規模】
對於50%的資料,1≤n≤500;
對於80%的資料,1≤n≤1000;
對於100%的資料,1≤n≤10,000。
題解:基於最長上升子序列改造,只不過這裡加了要求字典序最小,就是選擇某個位置之前的一個數是它最接近這個位置的數,就像輸入樣例2,1,7,5,9,6在9這個位置是選擇1,7,9這個序列而不選1,5,9這個序列,題意明白了,接下用來程式碼實現就行了。
import java.util.*; /* *大朋友的數字 */ public class test{ public static void main(String[] args) { Scanner in=new Scanner(System.in); int n=in.nextInt(); int[] a=new int[n+1]; for(int i=1;i<=n;i++) { a[i]=in.nextInt(); } int[] dp=new int[n+1]; int[] c=new int[n+1]; for(int i=1;i<=n;i++) { dp[i]=1; for(int j=1;j<i;j++) { if(a[i]>=a[j]) { if(dp[i]<dp[j]+1) { dp[i]=dp[j]+1; c[i]=c[j];//c[i]等於離它最近的一個數c[j]因為要求字典序最小 } } } c[i]+=a[i];//自身也是序列的一個數 } for(int i=1;i<=n;i++) { System.out.print(c[i]+" "); } } }