第一眼看到题目,感觉水水的,不就是最长下降子序列嘛!然后写……就呵呵了..要判重,还要高精度……判重我是在计算中加入各种判断。这道题比看上去麻烦一点,但其实还好吧..
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define rep(i,l,r) for(int i=l;i<r;i++) #define clr(x,c) memset(x,c,sizeof(x)) using namespace std; const int inf=0x3f3f3f3f,maxn=5000+5,maxv=100; int c[maxn],mdp[maxn],MDP[maxn][maxv]; int dp(int i) { if(mdp[i]>0) return mdp[i]; int ans=0; rep(j,0,i) if(c[j]>c[i]) ans=max(dp(j),ans); return mdp[i]=ans+1; } int main() { freopen("buylow.in","r",stdin); freopen("buylow.out","w",stdout); int n; cin>>n; rep(i,0,n) scanf("%d",&c[i]); clr(mdp,0); mdp[0]=1; clr(MDP,0); MDP[0][1]=1; MDP[0][0]=1; rep(i,1,n) if(dp(i)==1) { int pd=0; rep(j,0,i) if(c[j]==c[i] && dp(i)==dp(j)) pd=1; if(!pd) { MDP[i][0]=1; MDP[i][1]=1; } } else { int r=0; rep(j,0,i) if(dp(j)==dp(i) && c[i]==c[j]) r=j+1; rep(j,r,i) if(dp(j)+1==dp(i) && c[j]>c[i]) { int t=max(MDP[i][0],MDP[j][0]); rep(k,1,t+1) MDP[i][k]+=MDP[j][k]; rep(k,1,t+1) if(MDP[i][k]/10) { MDP[i][k+1]+=MDP[i][k]/10; MDP[i][k]%=10; } while(MDP[i][++t]) if(MDP[i][t]/10) { MDP[i][t+1]+=MDP[i][t]/10; MDP[i][t]%=10; } MDP[i][0]=--t; } } int ans=-1,cnt[maxv]; clr(cnt,0); rep(i,0,n) ans=max(dp(i),ans); rep(i,0,n) if(ans==dp(i)) { int t=max(cnt[0],MDP[i][0]); rep(j,1,t+1) cnt[j]+=MDP[i][j]; rep(j,1,t+1) if(cnt[j]/10) { cnt[j+1]+=cnt[j]/10; cnt[j]%=10; } while(cnt[++t]) if(cnt[t]/10) { cnt[t+1]+=cnt[t]/10; cnt[t]%=10; } cnt[0]=--t; } cout<<ans<<' '; for(int i=cnt[0];i>0;i--) cout<<cnt[i]; cout<<endl; return 0; }