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
*/

时间: 2024-10-16 11:54:06

usaco 4.3 Buy Low, Buy Lower的相关文章

算法练习 - Buy Low, Buy Lower - USACO

这道题目本身很简单,倒推回去,第K个是最优时,K+1时必然包含它.所以就从最后面的股票开始贪心法用最优解生成最优解. 难点1是去重,我直接用了个价格表去过滤,如果多个价格相等的同级最优解,就用他们中可能性最大的那个累加,其余的忽略. 难点2是大数计算.可能性可能有几十位的数字,所以封装了一个大数类.现在还不支持符号,只支持正数.后面需要用到负数的时候再说. 题目: Buy Low, Buy Lower The advice to "buy low" is half the formul

USACO Section 4.3 Buy low,Buy lower

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

【dp】PKU 1952 buy low,buy lower

题目链接: http://poj.org/problem?id=1952 Usaco 4.3.1 Buy Low, Buy Lower By 小兔齐齐 描述 “逢低吸纳”是炒股的一条成功秘诀.如果你想成为一个成功的投资者,就要遵守这条秘诀: "逢低吸纳,越低越买" 这句话的意思是:每次你购买股票时的股价一定要比你上次购买时的股价低.按照这个规则购买股票的次数越多越好,看看你最多能按这个规则买几次. 给定连续的N天中每天的股价.你可以在任何一天购买一次股票,但是购买时的股价一定要比你上次

POJ 1952 BUY LOW, BUY LOWER 动态规划题解

Description The advice to "buy low" is half the formula to success in the bovine stock market.To be considered a great investor you must also follow this problems' advice: "Buy low; buy lower" Each time you buy a stock, you must purcha

poj 1952 BUY LOW, BUY LOWER (最长递减子序列+不同子序列计数)

BUY LOW, BUY LOWER Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 8327   Accepted: 2888 Description The advice to "buy low" is half the formula to success in the bovine stock market.To be considered a great investor you must also f

POJ 1952 BUY LOW, BUY LOWER

BUY LOW, BUY LOWER Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 8311   Accepted: 2883 Description The advice to "buy low" is half the formula to success in the bovine stock market.To be considered a great investor you must also f

poj 1952 BUY LOW, BUY LOWER 最长下降子序列+统计不重复方案数

dp[i]=max(dp[i],dp[j]+1) j<i且a[j]>a[i] dp[i]表示长度为i的最长下降子序列的长度. r[i]表示长度为i的最长下降子序列的方案数. 考虑这样一个问题,比如6 3 9 3,对于两个3,他们数字一样并且dp值也一样,那么r[2]的方案数是没有意义的 因为能通过第一个3扩展的也能通过第二个3扩展,所以直接把r[2]=0. 对于一次扩展若dp[j]+1==dp[i],则说明j的路线和i的路线都可以用则r[i]+=r[j] 若dp[j]+1>dp[i],则

[POJ1952]BUY LOW, BUY LOWER

题目描述 Description The advice to "buy low" is half the formula to success in the bovine stock market.To be considered a great investor you must also follow this problems' advice: "Buy low; buy lower" Each time you buy a stock, you must p

poj 1952 BUY LOW, BUY LOWER[最长单调子序列变形]

题目:poj 1952 BUY LOW, BUY LOWER 题意:给出一个序列,先求最长单调递减子序列,然后求在子序列最长的情况下,不同的长度都为最长的的子序列的个数.(比如3,2,1和3,2,1属于相同,只能算一个) 分析:首先用一个dp[i]表示到当前i点的最长子序列的长度 用dp2[i]表示最长为dp[i]的子序列的个数 然后dp[i] = max(dp[j])+1 (1<=j /************************************ Problem: 1952 Use

POJ 1552 BUY LOW, BUY LOWER(最长单调递减子序列求方案数)

BUY LOW, BUY LOWER Time Limit: 1000MS   Memory Limit: 30000K       Description The advice to "buy low" is half the formula to success in the bovine stock market.To be considered a great investor you must also follow this problems' advice: "