• usaco 4.3 Buy Low, Buy Lower


    http://train.usaco.org/usacoprob2?a=7BaJNgFLmpD&S=buylow

    求最长递减子序列以及方案数,注意重复不算,比如 3 2 3 2 1 ,这里取到最长递减子序列算一种(3 2 1)。

    思路:

      最长递减子序列的长度可以直接dp: dp[i]=max(dp[j]+1) (j<i&&a[j]<a[i])。

      而方案数,如果不重复的话,在dp的过程中记录下就可以求了,设cnt[i]为以a[i]为结尾的方案数,那么推完dp的值之后再推一次,当dp[j]+1==dp[i](j<i)时,cnt[i]=cnt[j]。

           然而这里要求重复,那么问题就来了,如何判重,避开重复。

              思路是这样的:

                  对于序列........a[j]......a[i]......,如果a[i]==a[j],那么cnt[j]必然<=cnt[i],而且以a[j]为结尾的最有序列一定是以a[i]为结尾的最优序列的子集。

                  知道这一点之后思路就很简单了,计算cnt[i]时,遍历j=1~i,对于某个j,如果存在一个k,使j<k<i且a[k]==a[j],那么就不用把cnt[j]加进来了,这样就可以避免重复了。

      最后一个问题,这里要用高精度,自己写了个重载高精度,感觉还行。

    /*
    ID: huanrui ke
    PROG: buylow
    LANG: C++
    */
    #include<bits/stdc++.h>
    #define REP(i,a,b) for(int i=a;i<=b;i++)
    #define MS0(a) memset(a,0,sizeof(a))
    
    using namespace std;
    
    typedef long long ll;
    const int maxn=5010;
    const int INF=1e9+10;
    
    int n;
    ll a[maxn];
    int dp[maxn],Next[maxn];
    struct BigNum
    {
        int a[110],len;
        void init()
        {
            MS0(a);len=0;
        }
        void eq(ll x)
        {
            init();
            while(x){
                a[++len]=x%10;
                x/=10;
            }
        }
        /*
        friend BigNum operator=(BigNum A,ll x)
        {
            A.init();
            while(x){
                A.a[++len]=x%10;
                x/=10;
            }
            return A;
        }
        */
        friend BigNum operator+(BigNum A,BigNum B)
        {
            BigNum C;C.init();
            C.len=max(A.len,B.len)+1;
            int tag=0;
            REP(i,1,C.len){
                C.a[i]=A.a[i]+B.a[i]+tag;
                tag=C.a[i]/10;
                C.a[i]%=10;
            }
            bool flag=0;
            for(int i=C.len;i>=1;i--){
                if(C.a[i]){
                    flag=1;
                    C.len=i;break;
                }
            }
            if(!flag) C.len=1;
            return C;
        }
        void Print()
        {
            if(len==0) len=1;
            for(int i=len;i>=1;i--) printf("%d",a[i]);
        }
    };BigNum cnt[maxn];
    
    BigNum add(BigNum A,BigNum B)
    {
        return A+B;
    }
    
    int main()
    {
        #define ONLINE_JUDGE
        #ifndef ONLINE_JUDGE
            freopen("in.txt","r",stdin);
        #else
            freopen("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(int i=n;i>=1;i--){
                if(mp[a[i]]) Next[i]=mp[a[i]];
                else Next[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();puts("");
        }
        return 0;
    }
    /**
    
    6
    3 3 4 2 2 1
    6
    3 4 2 3 2 1
    1
    3
    5
    3 3 3 2 2
    6
    4 3 2 5 3 2
    */
    View Code
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    Docker+Jenkins持续集成环境(1)使用Docker搭建Jenkins+Docker持续集成环境
    DockOne技术分享(二十):Docker三剑客之Swarm介绍
    最佳实战Docker持续集成图文详解
    Spring Cloud Netflix Eureka源码导读与原理分析
    JVM内存区域的划分(内存结构或者内存模型)
    深入理解JVM(一)——JVM内存模型
    java多线程有哪些实际的应用场景?
    深入理解Java类加载器(1):Java类加载原理解析
    【深入Java虚拟机】之四:类加载机制
    OAuth 2和JWT
  • 原文地址:https://www.cnblogs.com/--560/p/5192131.html
Copyright © 2020-2023  润新知