Children’s Queue HDU

来源:互联网 发布:数据与安全监察委员会 编辑:程序博客网 时间:2024/06/10 20:09

There are many students in PHT School. One day, the headmaster whose name is PigHeader wanted all students stand in a line. He prescribed that girl can not be in single. In other words, either no girl in the queue or more than one girl stands side by side. The case n=4 (n is the number of children) is like
FFFF, FFFM, MFFF, FFMM, MFFM, MMFF, MMMM
Here F stands for a girl and M stands for a boy. The total number of queue satisfied the headmaster’s needs is 7. Can you make a program to find the total number of queue with n children?
Input
There are multiple cases in this problem and ended by the EOF. In each case, there is only one integer n means the number of children (1<=n<=1000)
Output
For each test case, there is only one integer means the number of queue satisfied the headmaster’s needs.
Sample Input
1
2
3
Sample Output
1
2
4

[分析]
这是一个递推的题目,代码其实很短就main里面一点点,其他都是大数模板,用了大数模板生活不能自理。

n个人的队列可以看作在n-1个的队列加上一个人。

在后面加男生的情况数就是a[n-1];

在后面加女生比较复杂,因为你不知道前面是否是一个女生;
但是你知道如果你在队尾加两个女生,那么这个队列肯定是合法的,所以就有a[n-2]种情况。
但是这样还不完整,比如你的n-2个人的队列最后一个人是一个single的女生,那么在这个人后面加两个女生也是合法队列,但这种队列情况不包含在a[n-2]中(因为最后只有一个女生的队列不合法)。
所以应该在n-4的队列中+男+女+女+女这样就正确了,所以这里有a[n-4]中情况

所以最后的状态方程是a[n]=a[n-1]+a[n-2]+a[n-4];

#include <algorithm> // max  #include <cassert>   // assert  #include <cstdio>    // printf,sprintf  #include <cstring>   // strlen  #include <iostream>  // cin,cout  #include <string>    // string类  #include <vector>    // vector类  using namespace std;struct BigInteger {    typedef unsigned long long LL;    static const int BASE = 100000000;    static const int WIDTH = 8;    vector<int> s;    BigInteger& clean() { while (!s.back() && s.size()>1)s.pop_back(); return *this; }    BigInteger(LL num = 0) { *this = num; }    BigInteger(string s) { *this = s; }    BigInteger& operator = (long long num) {        s.clear();        do {            s.push_back(num % BASE);            num /= BASE;        } while (num > 0);        return *this;    }    BigInteger& operator = (const string& str) {        s.clear();        int x, len = (str.length() - 1) / WIDTH + 1;        for (int i = 0; i < len; i++) {            int end = str.length() - i*WIDTH;            int start = max(0, end - WIDTH);            sscanf(str.substr(start, end - start).c_str(), "%d", &x);            s.push_back(x);        }        return (*this).clean();    }    BigInteger operator + (const BigInteger& b) const {        BigInteger c; c.s.clear();        for (int i = 0, g = 0; ; i++) {            if (g == 0 && i >= s.size() && i >= b.s.size()) break;            int x = g;            if (i < s.size()) x += s[i];            if (i < b.s.size()) x += b.s[i];            c.s.push_back(x % BASE);            g = x / BASE;        }        return c;    }    BigInteger operator - (const BigInteger& b) const {        assert(b <= *this); // 减数不能大于被减数          BigInteger c; c.s.clear();        for (int i = 0, g = 0; ; i++) {            if (g == 0 && i >= s.size() && i >= b.s.size()) break;            int x = s[i] + g;            if (i < b.s.size()) x -= b.s[i];            if (x < 0) { g = -1; x += BASE; }            else g = 0;            c.s.push_back(x);        }        return c.clean();    }    BigInteger operator * (const BigInteger& b) const {        int i, j; LL g;        vector<LL> v(s.size() + b.s.size(), 0);        BigInteger c; c.s.clear();        for (i = 0; i<s.size(); i++) for (j = 0; j<b.s.size(); j++) v[i + j] += LL(s[i])*b.s[j];        for (i = 0, g = 0; ; i++) {            if (g == 0 && i >= v.size()) break;            LL x = v[i] + g;            c.s.push_back(x % BASE);            g = x / BASE;        }        return c.clean();    }    BigInteger operator / (const BigInteger& b) const {        assert(b > 0);  // 除数必须大于0          BigInteger c = *this;       // 商:主要是让c.s和(*this).s的vector一样大          BigInteger m;               // 余数:初始化为0          for (int i = s.size() - 1; i >= 0; i--) {            m = m*BASE + s[i];            c.s[i] = bsearch(b, m);            m -= b*c.s[i];        }        return c.clean();    }    BigInteger operator % (const BigInteger& b) const { //方法与除法相同          BigInteger c = *this;        BigInteger m;        for (int i = s.size() - 1; i >= 0; i--) {            m = m*BASE + s[i];            c.s[i] = bsearch(b, m);            m -= b*c.s[i];        }        return m;    }    // 二分法找出满足bx<=m的最大的x      int bsearch(const BigInteger& b, const BigInteger& m) const {        int L = 0, R = BASE - 1, x;        while (1) {            x = (L + R) >> 1;            if (b*x <= m) { if (b*(x + 1)>m) return x; else L = x; }            else R = x;        }    }    BigInteger& operator += (const BigInteger& b) { *this = *this + b; return *this; }    BigInteger& operator -= (const BigInteger& b) { *this = *this - b; return *this; }    BigInteger& operator *= (const BigInteger& b) { *this = *this * b; return *this; }    BigInteger& operator /= (const BigInteger& b) { *this = *this / b; return *this; }    BigInteger& operator %= (const BigInteger& b) { *this = *this % b; return *this; }    bool operator < (const BigInteger& b) const {        if (s.size() != b.s.size()) return s.size() < b.s.size();        for (int i = s.size() - 1; i >= 0; i--)            if (s[i] != b.s[i]) return s[i] < b.s[i];        return false;    }    bool operator >(const BigInteger& b) const { return b < *this; }    bool operator<=(const BigInteger& b) const { return !(b < *this); }    bool operator>=(const BigInteger& b) const { return !(*this < b); }    bool operator!=(const BigInteger& b) const { return b < *this || *this < b; }    bool operator==(const BigInteger& b) const { return !(b < *this) && !(b > *this); }};ostream& operator << (ostream& out, const BigInteger& x) {    out << x.s.back();    for (int i = x.s.size() - 2; i >= 0; i--) {        char buf[20];        sprintf(buf, "%08d", x.s[i]);        for (int j = 0; j < strlen(buf); j++) out << buf[j];    }    return out;}istream& operator >> (istream& in, BigInteger& x) {    string s;    if (!(in >> s)) return in;    x = s;    return in;}int main(){    BigInteger a[1001];    a[0] = 1;    a[1] = 1;    a[2] = 2;    a[3] = 4;    a[4] = 7;    for (int i = 5; i < 1001; i++)    {        a[i] = a[i - 1] + a[i - 2] + a[i - 4];    }    int n;    while (scanf("%d", &n) != EOF)    {        cout << a[n] << endl;    }}
原创粉丝点击