• Codeforces Gym 100342D Problem D. Dinner Problem Dp+高精度


    Problem D. Dinner Problem
    Time Limit: 20 Sec

    Memory Limit: 256 MB

    题目连接

    http://codeforces.com/gym/100342/attachments

    Description

    A group of k students from Cooking University living in the campus decided that each day of the semester one of them will prepare the dinner for the whole company. The semester lasts for n days.
    In sake of fairness they decided that each of the students must prepare the dinner at least once during the semester. Now they wonder how many ways are there to plan the semester — to decide for each day which student would make a dinner that day. Help them to find that out.

    Input

    The input file contains two integer numbers k and n (1 ≤ k ≤ n ≤ 100).

    Output

    Output one integer number — the number of different nice paintings of the cottages.

    Sample Input

    2 3 

    Sample Output

    6

    HINT

    题意

    有n天,有k个人,安排这k个人做饭,问你有多少种安排方案,每个人至少得做一天饭

    题解

    简单DP,但是会爆longlong,要用高精度来搞一搞……

    java不会真是太伤心了= =

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <string>
    #include <algorithm>
    using namespace std;
    
    const int MAXN = 410;
    
    struct bign
    {
        int len, s[MAXN];
        bign ()
        {
            memset(s, 0, sizeof(s));
            len = 1;
        }
        bign (int num) { *this = num; }
        bign (const char *num) { *this = num; }
        bign operator = (const int num)
        {
            char s[MAXN];
            sprintf(s, "%d", num);
            *this = s;
            return *this;
        }
        bign operator = (const char *num)
        {
            for(int i = 0; num[i] == '0'; num++) ;  //去前导0
            len = strlen(num);
            for(int i = 0; i < len; i++) s[i] = num[len-i-1] - '0';
            return *this;
        }
        bign operator + (const bign &b) const //+
        {
            bign c;
            c.len = 0;
            for(int i = 0, g = 0; g || i < max(len, b.len); i++)
            {
                int x = g;
                if(i < len) x += s[i];
                if(i < b.len) x += b.s[i];
                c.s[c.len++] = x % 10;
                g = x / 10;
            }
            return c;
        }
        bign operator += (const bign &b)
        {
            *this = *this + b;
            return *this;
        }
        void clean()
        {
            while(len > 1 && !s[len-1]) len--;
        }
        bign operator * (const bign &b) //*
        {
            bign c;
            c.len = len + b.len;
            for(int i = 0; i < len; i++)
            {
                for(int j = 0; j < b.len; j++)
                {
                    c.s[i+j] += s[i] * b.s[j];
                }
            }
            for(int i = 0; i < c.len; i++)
            {
                c.s[i+1] += c.s[i]/10;
                c.s[i] %= 10;
            }
            c.clean();
            return c;
        }
        bign operator *= (const bign &b)
        {
            *this = *this * b;
            return *this;
        }
        bign operator - (const bign &b)
        {
            bign c;
            c.len = 0;
            for(int i = 0, g = 0; i < len; i++)
            {
                int x = s[i] - g;
                if(i < b.len) x -= b.s[i];
                if(x >= 0) g = 0;
                else
                {
                    g = 1;
                    x += 10;
                }
                c.s[c.len++] = x;
            }
            c.clean();
            return c;
        }
        bign operator -= (const bign &b)
        {
            *this = *this - b;
            return *this;
        }
        bign operator / (const bign &b)
        {
            bign c, f = 0;
            for(int i = len-1; i >= 0; i--)
            {
                f = f*10;
                f.s[0] = s[i];
                while(f >= b)
                {
                    f -= b;
                    c.s[i]++;
                }
            }
            c.len = len;
            c.clean();
            return c;
        }
        bign operator /= (const bign &b)
        {
            *this  = *this / b;
            return *this;
        }
        bign operator % (const bign &b)
        {
            bign r = *this / b;
            r = *this - r*b;
            return r;
        }
        bign operator %= (const bign &b)
        {
            *this = *this % b;
            return *this;
        }
        bool operator < (const bign &b)
        {
            if(len != b.len) return len < b.len;
            for(int i = len-1; i >= 0; i--)
            {
                if(s[i] != b.s[i]) return s[i] < b.s[i];
            }
            return false;
        }
        bool operator > (const bign &b)
        {
            if(len != b.len) return len > b.len;
            for(int i = len-1; i >= 0; i--)
            {
                if(s[i] != b.s[i]) return s[i] > b.s[i];
            }
            return false;
        }
        bool operator == (const bign &b)
        {
            return !(*this > b) && !(*this < b);
        }
        bool operator != (const bign &b)
        {
            return !(*this == b);
        }
        bool operator <= (const bign &b)
        {
            return *this < b || *this == b;
        }
        bool operator >= (const bign &b)
        {
            return *this > b || *this == b;
        }
        string str() const
        {
            string res = "";
            for(int i = 0; i < len; i++) res = char(s[i]+'0') + res;
            return res;
        }
    };
    
    istream& operator >> (istream &in, bign &x)
    {
        string s;
        in >> s;
        x = s.c_str();
        return in;
    }
    
    ostream& operator << (ostream &out, const bign &x)
    {
        out << x.str();
        return out;
    }
    
    int n , k ;
    bign dp[105][105];
    
    
    bign dfs(int i ,int j)
    {
        if (dp[i][j] != -1) return dp[i][j];
        if (i > j)
        {
            return dp[i][j] = 0;
        }
        else if(i == 0 && j == 0) return dp[i][j] = 1;
        else if(i == 0) return dp[i][j] = dfs(i,j-1) * k;
        else return dp[i][j] = dfs(i-1,j-1) * i + dfs(i,j-1) * (k-i);
    }
    
    
    int main()
    {
        freopen("dinner.in","r",stdin);
        freopen("dinner.out","w",stdout);
        cin >> k >> n;
        for(int i = 0 ; i <= 100 ; ++ i)
         for(int j = 0 ; j <= 100 ; ++ j)
             dp[i][j] = -1;
        bign ans = dfs(k,n);
        cout << ans << endl;
        return 0;
    }
  • 相关阅读:
    Android DisplayMetrics 获取和屏幕相关的信息
    【IOS开发—视图控制器】
    【IOS开发—视图】
    【Spdy协议简介】
    三维数组
    一维数组
    闰年判断
    使用switch case语句来显示月份的对应天数
    使用for循环嵌套实现乘法口诀表
    判断一个数的奇偶性
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4708809.html
Copyright © 2020-2023  润新知