程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU 1297——Children’s Queue

HDU 1297——Children’s Queue

編輯:C++入門知識

遞推問題實現起來很簡單,但得到遞推公式確實很麻煩,就像DP一樣。 分析(部分出自HDU的PPT): 設:F(n)表示n個人的合法隊列,則: 按照最後一個人的性別分析,他要麼是男,要麼是女,所以可以分兩大類討論:  1、如果n個人的合法隊列的最後一個人是男,則對前面n-1個人的隊列沒有任何限制,他只要站在最後即可,所以,這種情況一共有F(n-1); 2、如果n個人的合法隊列的最後一個人是女,則要求隊列的第n-1個人務必也是女生,這就是說,限定了最後兩個人必須都是女生,這又可以分兩種情況: (1)、如果隊列的前n-2個人是合法的隊列,則顯然後面再加兩個女生,也一定是合法的,這種情況有F(n-2); (2)難點在於,即使前面n-2個人不是合法的隊列,加上兩個女生也有可能是合法的,當然,這種長度為n-2的不合法隊列,不合法的地方必須是尾巴,就是說,這裡說的長度是n-2的不合法串的形式必須是“F(n-4)+男+女”,這種情況一共有F(n-4).   所以遞推公式為F(n)=F(n-1)+F(n-2)+F(n-4). 另外需要注意的是 這個遞推式的數據范圍到了1000,int甚至long long 都已經無法承載最大邊界,所以我使用了前兩天貼出的大數類。 [cpp]   #include<iostream>    #include<string>    #include<iomanip>    #include<algorithm>    using namespace std;       #define MAXN 9999   #define MAXSIZE 10   #define DLEN 4      class BigNum   {    private:        int a[500];    //可以控制大數的位數        int len;       //大數長度   public:        BigNum(){ len = 1;memset(a,0,sizeof(a)); }   //構造函數       BigNum(const int);       //將一個int類型的變量轉化為大數       BigNum(const char*);     //將一個字符串類型的變量轉化為大數       BigNum(const BigNum &);  //拷貝構造函數       BigNum &operator=(const BigNum &);   //重載賦值運算符,大數之間進行賦值運算          friend istream& operator>>(istream&,  BigNum&);   //重載輸入運算符       friend ostream& operator<<(ostream&,  BigNum&);   //重載輸出運算符          BigNum operator+(const BigNum &) const;   //重載加法運算符,兩個大數之間的相加運算        BigNum operator-(const BigNum &) const;   //重載減法運算符,兩個大數之間的相減運算        BigNum operator*(const BigNum &) const;   //重載乘法運算符,兩個大數之間的相乘運算        BigNum operator/(const int   &) const;    //重載除法運算符,大數對一個整數進行相除運算          BigNum operator^(const int  &) const;    //大數的n次方運算       int    operator%(const int  &) const;    //大數對一個int類型的變量進行取模運算           bool   operator>(const BigNum & T)const;   //大數和另一個大數的大小比較       bool   operator>(const int & t)const;      //大數和一個int類型的變量的大小比較          void print();       //輸出大數   };    BigNum::BigNum(const int b)     //將一個int類型的變量轉化為大數   {        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;   }   BigNum::BigNum(const char*s)     //將一個字符串類型的變量轉化為大數   {       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;       }   }   BigNum::BigNum(const BigNum & T) : len(T.len)  //拷貝構造函數   {        int i;        memset(a,0,sizeof(a));        for(i = 0 ; i < len ; i++)           a[i] = T.a[i];    }    BigNum & BigNum::operator=(const BigNum & 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,  BigNum & 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,  BigNum& 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;   }      BigNum BigNum::operator+(const BigNum & T) const   //兩個大數之間的相加運算   {       BigNum 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;   }   BigNum BigNum::operator-(const BigNum & T) const   //兩個大數之間的相減運算    {         int i,j,big;       bool flag;       BigNum 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[len - 1] == 0 && t1.len > 1)       {           t1.len--;            big--;       }       if(flag)           t1.a[big-1]=0-t1.a[big-1];       return t1;    }       BigNum BigNum::operator*(const BigNum & T) const   //兩個大數之間的相乘運算    {        BigNum 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;    }    BigNum BigNum::operator/(const int & b) const   //大數對一個整數進行相除運算   {        BigNum 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;    }   int BigNum::operator %(const int & b) const    //大數對一個int類型的變量進行取模運算       {       int i,d=0;       for (i = len-1; i>=0; i--)       {           d = ((d * (MAXN+1))% b + a[i])% b;         }       return d;   }   BigNum BigNum::operator^(const int & n) const    //大數的n次方運算   {       BigNum 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 BigNum::operator>(const BigNum & T) const   //大數和另一個大數的大小比較   {        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 BigNum::operator >(const int & t) const    //大數和一個int類型的變量的大小比較   {       BigNum b(t);       return *this>b;   }      void BigNum::print()    //輸出大數   {        int i;          cout << a[len - 1];        for(i = len - 2 ; i >= 0 ; i--)       {            cout.width(DLEN);            cout.fill('0');            cout << a[i];        }        cout << endl;   }      BigNum que[1202];   //上邊不是主要作用。。   int main()   {       que[0]=1;       que[1]=1;       que[2]=2;       que[3]=4;       for(int i=4;i<=1000;i++)       {           que[i]=que[i-1]+que[i-2]+que[i-4];       }       int tar;       while(cin>>tar)       {           que[tar].print();       }       return 0;   }    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved