USACO Section 4.3 Buy low,Buy lower(LIS)

第一眼看到题目,感觉水水的,不就是最长下降子序列嘛!然后写……就呵呵了..要判重,还要高精度……判重我是在计算中加入各种判断。这道题比看上去麻烦一点,但其实还好吧..

#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;
}
View Code

相关文章: