URAL 1036(数位dp)

来源:互联网 发布:2017淘宝全年的交易额 编辑:程序博客网 时间:2024/06/05 10:12

问题描述:

You are given a number 1 ≤ N ≤ 50. Every ticket has its 2 N-digit number. We call a ticket lucky, if the sum of its first N digits is equal to the sum of its last Ndigits. You are also given the sum of ALL digits in the number. Your task is to count an amount of lucky numbers, having the specified sum of ALL digits.

Input

Two space-separated numbers: N and S. Here S is the sum of all digits. Assume that 0 ≤ S ≤ 1000.

Output

The amount of lucky tickets.

2 2

4

题目题意:有一个2*n长度的数字,我们要求前面n个数的和等于后面n个数的和,前面和后面的总和是s,问数字有多少种。

dp[i][j]表示前面i位和为j的种类数。注意大数

代码如下:

#include<iostream>#include<cmath>#include<cstring>#include<cstdio>using namespace std;const int MAXN=150;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){    if (x.str()=="") out<<0;    else out << x.str();    return out;}bign dp[55][520];int main(){    int n,s;    while (scanf("%d%d",&n,&s)!=EOF) {        if (s%2==1) {            printf("%d\n",0);            continue;        }        s=s/2;        for (int i=0;i<55;i++) {            for (int j=0;j<520;j++) {                dp[i][j]=0;            }        }        dp[0][0]=1;        for (int i=1;i<=n;i++) {            for (int j=0;j<=s;j++) {                for (int k=0;k<=9;k++) {                    if (j-k>=0) dp[i][j]+=dp[i-1][j-k];                }            }        }        bign ans=dp[n][s]*dp[n][s];        cout<<ans<<endl;    }    return 0;}
















原创粉丝点击