HDU 5568 sequence2(大数+DP)

题意:给一个序列,问有多少个长度为k的上升子序列(对i < j有a[i] < a[j])。

思路:看到上升子序列应想到dp。dp[i][j]表示以a[i]结尾长度为j的上升子序列有多少个。那么得到转移方程:dp[i][j] = sum{dp[k][j-1]},其中 1 <= k < i。

注意此题要用大数BigInteger。

#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <cmath>
#include <set>
#include <map>
using namespace std;

typedef long long LL;
#define mem(a, n) memset(a, n, sizeof(a))
#define ALL(v) v.begin(), v.end()
#define si(a) scanf("%d", &a)
#define sii(a, b) scanf("%d%d", &a, &b)
#define siii(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define pb push_back
#define eps 1e-8
const int inf = 0x3f3f3f3f, N = 1e2 + 5;

int T, cas = 0;
int n, k;
int a[N];

 #define MAXN 9999
 #define MAXSIZE 10
 #define DLEN 4
 const long long MOD = 258280327;
  class BigInteger
 {
 private:
     int a[300];   // Width 
     int len;       // Length
 public:
     BigInteger(){ len = 1; memset(a, 0, sizeof(a)); }   //Init
     BigInteger(const int);       // Int -> BigInt
     BigInteger(const char*);     // String -> BigInt
     BigInteger(const BigInteger &);  // copy
     BigInteger &operator=(const BigInteger &);   // =
 
     friend istream& operator>>(istream&, BigInteger&);   // >>
     friend ostream& operator<<(ostream&, BigInteger&);   // <<
 
     BigInteger operator+(const BigInteger &) const;   // +
     BigInteger operator-(const BigInteger &) const;   // -
     BigInteger operator*(const BigInteger &) const;   // *
     BigInteger operator/(const int   &) const;        // /
 
     BigInteger operator^(const int  &) const;    //BigInt Pow
     long long    operator%(const long long  &) const;    //Mod Int
     bool   operator>(const BigInteger & T)const;   //Compare with BigInt
     bool   operator<(const BigInteger & T)const;
     bool   operator>(const int & t)const;      //Compare with Int
 
     void print();       //输出大数
 };
 BigInteger::BigInteger(const int b)     //Int - > BigInt
 {
     int c, d = b;
     len = 0;
     memset(a, 0, sizeof(a));
     while (d > MAXN)
     {
         c = d - (d / (MAXN + 1)) * (MAXN + 1);
         d = d / (MAXN + 1);
         a[len++] = c;
     }
     a[len++] = d;
 }
 BigInteger::BigInteger(const char*s)     //String -> BigInt
 {
     int t, k, index, l, i;
     memset(a, 0, sizeof(a));
     l = strlen(s);
     len = l / DLEN;
     if (l%DLEN)
         len++;
     index = 0;
     for (i = l - 1; i >= 0; i -= DLEN)
     {
         t = 0;
         k = i - DLEN + 1;
         if (k<0)
             k = 0;
         for (int j = k; j <= i; j++)
             t = t * 10 + s[j] - '0';
         a[index++] = t;
     }
 }
 BigInteger::BigInteger(const BigInteger & T) : len(T.len)  // copy
 {
     int i;
      memset(a, 0, sizeof(a));
     for (i = 0; i < len; i++)
         a[i] = T.a[i];
 }
 BigInteger & BigInteger::operator=(const BigInteger & n)   //=
 {
     int i;
     len = n.len;
     memset(a, 0, sizeof(a));
     for (i = 0; i < len; i++)
         a[i] = n.a[i];
     return *this;
 }
 istream& operator>>(istream & in, BigInteger & b)   //>>
 {
     char ch[MAXSIZE * 4];
     int i = -1;
     in >> ch;
     int l = strlen(ch);
     int count = 0, sum = 0;
     for (i = l - 1; i >= 0;)
     {
         sum = 0;
         int t = 1;
         for (int j = 0; j<4 && i >= 0; j++, i--, t *= 10)
         {
             sum += (ch[i] - '0')*t;
         }
         b.a[count] = sum;
         count++;
     }
     b.len = count++;
     return in;
 }
 ostream& operator<<(ostream& out, BigInteger& b)   // <<
 {
     int i;
     cout << b.a[b.len - 1];
     for (i = b.len - 2; i >= 0; i--)
     {
         cout.width(DLEN);
         cout.fill('0');
         cout << b.a[i];
     }
     return out;
 }

 BigInteger BigInteger::operator+(const BigInteger & T) const   //+
 {
     BigInteger t(*this);
     int i, big;      //位数
     big = T.len > len ? T.len : len;
     for (i = 0; i < big; i++)
     {
         t.a[i] += T.a[i];
         if (t.a[i] > MAXN)
         {
             t.a[i + 1]++;
             t.a[i] -= MAXN + 1;
         }
     }
     if (t.a[big] != 0)
         t.len = big + 1;
     else
         t.len = big;
     return t;
 }
 BigInteger BigInteger::operator-(const BigInteger & T) const   // -
 {
     int i, j, big;
     bool flag;
     BigInteger t1, t2;
     if (*this>T)
     {
         t1 = *this;
         t2 = T;
         flag = 0;
     }
     else
     {
         t1 = T;
         t2 = *this;
         flag = 1;
     }
     big = t1.len;
     for (i = 0; i < big; i++)
     {
         if (t1.a[i] < t2.a[i])
         {
             j = i + 1;
             while (t1.a[j] == 0)
                 j++;
             t1.a[j--]--;
             while (j > i)
                 t1.a[j--] += MAXN;
             t1.a[i] += MAXN + 1 - t2.a[i];
         }
         else
             t1.a[i] -= t2.a[i];
     }
     t1.len = big;
     while (t1.a[t1.len - 1] == 0 && t1.len > 1)
     {
         t1.len--;
         big--;
     }
     if (flag)
         t1.a[big - 1] = 0 - t1.a[big - 1];
     return t1;
 }
 
 BigInteger BigInteger::operator*(const BigInteger & T) const   //Mutiply with BigInteger
 {
     BigInteger ret;
     int i, j, up;
     int temp, temp1;
     for (i = 0; i < len; i++)
     {
         up = 0;
         for (j = 0; j < T.len; j++)
         {
             temp = a[i] * T.a[j] + ret.a[i + j] + up;
             if (temp > MAXN)
             {
                 temp1 = temp - temp / (MAXN + 1) * (MAXN + 1);
                 up = temp / (MAXN + 1);
                 ret.a[i + j] = temp1;
             }
             else
             {
                 up = 0;
                 ret.a[i + j] = temp;
             }
         }
         if (up != 0)
             ret.a[i + j] = up;
     }
     ret.len = i + j;
     while (ret.a[ret.len - 1] == 0 && ret.len > 1)
         ret.len--;
     return ret;
 }
 BigInteger BigInteger::operator/(const int & b) const   //Divide Int
 {
     BigInteger ret;
     int i, down = 0;
     for (i = len - 1; i >= 0; i--)
     {
         ret.a[i] = (a[i] + down * (MAXN + 1)) / b;
         down = a[i] + down * (MAXN + 1) - ret.a[i] * b;
     }
     ret.len = len;
     while (ret.a[ret.len - 1] == 0 && ret.len > 1)
         ret.len--;
     return ret;
 }
 long long BigInteger::operator %(const long long & b) const    //Mod Int
 {
     int i;
     long long d = 0;
     for (i = len - 1; i >= 0; i--)
     {
         d = ((d * (MAXN + 1)) % b + (long long)(a[i])) % b;
     }
     return d;
 }
 BigInteger BigInteger::operator^(const int & n) const    //Pow of BigInteger
 {
     BigInteger t, ret(1);
     int i;
     if (n<0)
         exit(-1);
     if (n == 0)
         return 1;
     if (n == 1)
         return *this;
     int m = n;
     while (m>1)
     {
         t = *this;
         for (i = 1; i << 1 <= m; i <<= 1)
         {
             t = t*t;
         }
         m -= i;
         ret = ret*t;
         if (m == 1)
             ret = ret*(*this);
     }
     return ret;
 }
 bool BigInteger::operator>(const BigInteger & T) const   //Compare with BigInteger
 {
     int ln;
     if (len > T.len)
         return true;
     else if (len == T.len)
     {
         ln = len - 1;
         while (a[ln] == T.a[ln] && ln >= 0)
             ln--;
         if (ln >= 0 && a[ln] > T.a[ln])
             return true;
         else
             return false;
     }
     else
         return false;
 }
 bool BigInteger::operator<(const BigInteger & T) const   //Compare with BigInteger
 {
     int ln;
     if (len > T.len)
         return true;
     else if (len == T.len)
     {
         ln = len - 1;
         while (a[ln] == T.a[ln] && ln >= 0)
             ln--;
         if (ln >= 0 && a[ln] < T.a[ln])
             return true;
         else
             return false;
     }
     else
         return false;
 }
 bool BigInteger::operator >(const int & t) const    //Compare with Int
 {
     BigInteger b(t);
     return *this>b;
 }
 
 void BigInteger::print()    //Print BigInteger
 {
     int i;
     cout << a[len - 1];
     for (i = len - 2; i >= 0; i--)
     {
         cout.width(DLEN);
         cout.fill('0');
         cout << a[i];
     }
     cout << endl;
 }
BigInteger dp[N][N];

int main(){
#ifdef LOCAL
    freopen("/Users/apple/input.txt", "r", stdin);
//	freopen("/Users/apple/out.txt", "w", stdout);
#endif
	
    while(sii(n, k) != EOF) {
    	mem(dp, 0);
    	for(int i = 1; i <= n; i ++) si(a[i]), dp[i][1] = 1;
    	for(int i = 1; i <= n; i ++) {
    		for(int j = 2; j <= k; j ++) {
    			dp[i][j] = 0;
    			for(int k = 1; k < i; k ++) {
    				if(a[k] < a[i]) {
    					dp[i][j] = dp[i][j] + dp[k][j-1];
    				}
    			}
    		}
    	}
    	BigInteger ans = 0;
    	for(int i = 1; i <= n; i ++) ans = ans + dp[i][k];
    	cout << ans << endl;
    }
    
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值