Http://train.usaco.org/usacoprob2?a=7BaJNgFLmpD&S=buylow
To find the longest descending subsequence and the number of schemes, note that repetition does not count, such as 3 2 3 2 1, where the longest descending subsequence is counted as one (3 2 1).
Ideas:
The length of the longest descending subsequence can be directly Dp:dp[i]=max (dp[j]+1) (J<i&&a[j]<a[i]).
and the program number, if not repeated, in the process of DP recording can be asked, set Cnt[i] to the end of A[i] as the number of scenarios, then push the value of DP after push again, when Dp[j]+1==dp[i] (j<i), Cnt[i]=cnt[j].
However, this requires repetition, and then the question comes, how to judge the weight and avoid repetition.
The idea is this:
For sequences ... a[j]......a[i] ..., if A[I]==A[J], then cnt[j] must <=cnt[i], and the most sequence ending with a[j] must be a subset of the optimal sequence ending with a[i].
Know this after the idea is very simple, calculate cnt[i], traverse J=1~i, for a J, if there is a K, so j<k<i and A[k]==a[j], then do not have to add the cnt[j, so you can avoid duplication.
The last problem, here to use high-precision, wrote a heavy-duty high-precision, the feeling is OK.
/*Id:huanrui keprog:buylowlang:c++*/#include<bits/stdc++.h>#defineREP (I,A,B) for (int i=a;i<=b;i++)#defineMS0 (a) memset (A,0,sizeof (a))using namespaceStd;typedefLong Longll;Const intmaxn=5010;Const intinf=1e9+Ten;intN;ll A[MAXN];intDP[MAXN],NEXT[MAXN];structbignum{inta[ the],len; voidinit () {MS0 (a); Len=0; } voideq (ll x) {init (); while(x) {a[++len]=x%Ten; X/=Ten; } } /*friend Bignum operator= (bignum a,ll x) {a.init (); while (x) {a.a[++len]=x%10; x/=10; } return A; } */friend Bignumoperator+(bignum a,bignum B) {bignum C; C.init (); C.len=max (A.len,b.len) +1; inttag=0; REP (i,1, C.len) {C.a[i]=a.a[i]+b.a[i]+tag; Tag=c.a[i]/Ten; C.a[i]%=Ten; } BOOLflag=0; for(inti=c.len;i>=1; i--){ if(C.a[i]) {flag=1; C.len=i; Break; } } if(!flag) c.len=1; returnC; } voidPrint () {if(len==0) len=1; for(inti=len;i>=1; i--) printf ("%d", A[i]); }}; Bignum CNT[MAXN]; Bignum Add (bignum a,bignum B) {returnA +B;}intMain () {#defineOnline_judge#ifndef Online_judge freopen ("In.txt","R", stdin); #elseFreopen ("buylow.in","R", stdin); Freopen ("Buylow.out","W", stdout); #endif while(cin>>N) {REP (i,1, N) scanf ("%d",&A[i]); a[++n]=0; memset (Next,-1,sizeof(Next)); Map<ll,int>MP; for(inti=n;i>=1; i--){ if(Mp[a[i]]) next[i]=Mp[a[i]]; Elsenext[i]=-1; Mp[a[i]]=i; } REP (I,1, N) {Dp[i]=1; REP (J,1, I-1){ if(a[j]>A[i]) {Dp[i]=max (dp[i],dp[j]+1); }}} REP (I,1, N) cnt[i].init (); REP (i,1, N) { if(dp[i]==1) {Cnt[i].eq (1); Continue; } REP (J,1, I-1){ if(a[j]>A[i]) { if(dp[j]+1==Dp[i]) { if(next[j]!=-1&&next[j]<i)Continue; Cnt[i]=Add (Cnt[i],cnt[j]); } } } } //REP (i,1,n) cout<<dp[i]<< "";cout<<endl; //REP (i,1,n) cout<<cnt[i]<< "";cout<<endl;printf"%d", dp[n]-1); Cnt[n]. Print ();p UTS (""); } return 0;}/**63 3 4 2 2 163 4 2 3 2 11353 3 3 2 3 2 5 3 2*/
View Code
Usaco 4.3 buy low, buy Lower