Essentially a longest decreasing sequence problem that is easy to solve using typical DP approach. Counting the number of such sequences is also not hard, the real problem is that the counts could be too big to fit in 32 or 64 bit integers, so need to use big integers struct.
#include  <vector>  #include  <iostream>  #include  <fstream>  #include  <climits>  #include  <algorithm>  #include  <iomanip>  using  namespace  std ;const  int  base = 1000000000 ;const  int  base_digits = 9 ;struct  BigInteger {    vector <int > a;     int  sign;     BigInteger() : sign(1 ) {}     BigInteger(long  long  v) {         *this  = v;     }     void  operator =(const  BigInteger &v) {         sign = v.sign;         a = v.a;     }     void  operator =(long  long  v) {         sign = 1 ;         a.clear();         if  (v < 0 ) {             sign = -1 , v = -v;         }         for  (; v > 0 ; v = v / base) {             a.push_back(v % base);         }     }     BigInteger operator +(const  BigInteger &v) const  {         if  (sign != v.sign) return  *this  - (-v);         BigInteger res = v;         for  (int  i = 0 , carry = 0 ;              i < (int ) max(a.size(), v.a.size()) || carry; ++i) {             if  (i == (int ) res.a.size())                 res.a.push_back(0 );             res.a[i] += carry + (i < (int ) a.size() ? a[i] : 0 );             carry = res.a[i] >= base;             if  (carry) res.a[i] -= base;         }         return  res;     }     BigInteger operator -(const  BigInteger &v) const  {         if  (sign != v.sign) return  *this  + (-v);         if  (abs () < v.abs ()) return  -(v - *this );         BigInteger res = *this ;         for  (int  i = 0 , carry = 0 ; i < (int ) v.a.size() || carry; ++i) {             res.a[i] -= carry + (i < (int ) v.a.size() ? v.a[i] : 0 );             carry = res.a[i] < 0 ;             if  (carry)                 res.a[i] += base;         }         res.trim();         return  res;     }     void  operator +=(const  BigInteger &v) {         *this  = *this  + v;     }     void  operator -=(const  BigInteger &v) {         *this  = *this  - v;     }     bool  operator <(const  BigInteger &v) const  {         if  (sign != v.sign)             return  sign < v.sign;         if  (a.size() != v.a.size())             return  a.size() * sign < v.a.size() * v.sign;         for  (int  i = (int )a.size() - 1 ; i >= 0 ; i--)             if  (a[i] != v.a[i])                 return  a[i] * sign < v.a[i] * sign;         return  false ;     }     bool  operator >(const  BigInteger &v) const  {         return  v < *this ;     }     bool  operator  <= (const  BigInteger &v) const  { return  !(v < *this ); }     bool  operator  >= (const  BigInteger &v) const  { return  !(*this  < v); }     bool  operator  == (const  BigInteger &v) const  {         return  !(*this  < v) && !(v < *this );     }     bool  operator  != (const  BigInteger &v) const  { return  *this  < v || v < *this ; }     void  trim ()           while  (!a.empty() && !a.back())             a.pop_back();         if  (a.empty())             sign = 1 ;     }     BigInteger operator -() const  {         BigInteger res = *this ;         res.sign = -sign;         return  res;     }     BigInteger abs ()  const   {         BigInteger res = *this ;         res.sign *= res.sign;         return  res;     }     friend  ostream& operator <<(ostream &stream, const  BigInteger &v) {         if  (v.sign == -1 )             stream << '-' ;         stream << (v.a.empty() ? 0  : v.a.back());         for  (int  i = (int ) v.a.size() - 2 ; i >= 0 ; --i)             stream << setw(base_digits) << setfill('0' ) << v.a[i];         return  stream;     } }; int  N;vector <int > num, dp;vector <BigInteger> cnt;int  main ()      ifstream fin ("buylow.in" )  ;     ofstream fout ("buylow.out" )  ;     fin >> N;     num = vector <int >(N, 0 );     dp = vector <int >(N, 0 );     cnt = vector <BigInteger>(N, BigInteger(0 ));     for  (int  i = 0 ; i < N; ++i) {         fin >> num[i];     }     dp[0 ] = 1 ; cnt[0 ] = 1 ;     for  (int  i = 0 ; i < N; ++i) {         dp[i] = 1 ;         for  (int  j = 0 ; j < i; ++j) {             if  (num[j] > num[i]) {                 dp[i] = std ::max(dp[i], dp[j] + 1 );             }         }         for  (int  j = 0 ; j < i; ++j) {             if  (num[j] > num[i] && dp[i] == dp[j] + 1 ) {                 cnt[i] += cnt[j];             }         }         if  (cnt[i] == 0 ) cnt[i] = 1 ;         for  (int  j = 0 ; j < i; ++j) {             if  (num[j] == num[i] && dp[j] == dp[i]) {                 cnt[i] -= cnt[j];              }         }     }     int  maxLen = *std ::minmax_element(dp.begin(), dp.end()).second;     BigInteger finalCnt = 0 ;     for  (int  i = 0 ; i < N; ++i) {         if  (maxLen == dp[i]) {             finalCnt += cnt[i];         }     }     cout  << maxLen << " "  << finalCnt << endl ;     fout << maxLen << " "  << finalCnt << endl ; }