DP+高精度 URAL 1036 Lucky Tickets

 

题目传送门

  1 /*
  2     题意:转换就是求n位数字,总和为s/2的方案数
  3     DP+高精度:状态转移方程:dp[cur^1][k+j] = dp[cur^1][k+j] + dp[cur][k];
  4                 高精度直接拿JayYe的:)
  5     异或运算的规则:
  6     0⊕0=0,0⊕1=1
  7     1⊕0=1,1⊕1=0
  8     口诀:相同取0,相异取1
  9 */
 10 #include <cstdio>
 11 #include <cstring>
 12 #include <string>
 13 #include <iostream>
 14 #include <algorithm>
 15 using namespace std;
 16 
 17 const int numlen = 1005;
 18 const int numbit = 4;
 19 const int addbit = 10000;
 20 const int maxn = numlen/numbit + 10;
 21 
 22 struct bign {
 23     int len, s[numlen];
 24     bign() {
 25         memset(s, 0, sizeof(s));
 26         len = 1;
 27     }
 28     bign(int num) { *this = num; }
 29     bign(const char *num) { *this = num; }
 30     bign operator = (const int num) {
 31         char s[numlen];
 32         sprintf(s, "%d", num);
 33         *this = s;
 34         return *this;
 35     }
 36     bign operator = (const char *num){
 37         int clen = strlen(num);
 38         while(clen > 1 && num[0] == '0')    num++, clen--;
 39         len = 0;
 40         for(int i = clen-1;i >= 0; i -= numbit) {
 41             int top = min(numbit, i+1), mul = 1;
 42             s[len] = 0;
 43             for(int j = 0;j < top; j++) {
 44                 s[len] += (num[i-j]-'0')*mul;
 45                 mul *= 10;
 46             }
 47             len++;
 48         }
 49         deal();
 50         return *this;
 51     }
 52     void deal() {
 53         while(len > 1 && !s[len-1]) len--;
 54     }
 55     bign operator + (const bign &a) const {
 56         bign ret;
 57         ret.len = 0;
 58         int top = max(len, a.len), add = 0;
 59         for(int i = 0;add || i < top; i++) {
 60             int now = add;
 61             if(i < len) now += s[i];
 62             if(i < a.len)   now += a.s[i];
 63             ret.s[ret.len++] = now%addbit;
 64             add = now/addbit;
 65         }
 66         return ret;
 67     }
 68     bign operator * (const bign &a)const {
 69         bign ret;
 70         ret.len = len + a.len;
 71         for(int i = 0;i < len; i++) {
 72             int pre = 0;
 73             for(int j = 0;j < a.len; j++) {
 74                 int now = s[i]*a.s[j] + pre;
 75                 pre = 0;
 76                 ret.s[i+j] += now;
 77                 if(ret.s[i+j] >= addbit) {
 78                     pre = ret.s[i+j]/addbit;
 79                     ret.s[i+j] -= pre*addbit;
 80                 }
 81             }
 82             if(pre) ret.s[i+a.len] = pre;
 83         }
 84         ret.deal();
 85         return ret;
 86     }
 87 }dp[2][1005];
 88 istream& operator >> (istream &in, bign &x) {
 89     string s;
 90     in >> s;
 91     x = s.c_str();
 92     return in;
 93 }
 94 ostream& operator << (ostream &out, const bign &x) {
 95     printf("%d", x.s[x.len-1]);
 96     for(int i = x.len-2;i >= 0; i--)    printf("%04d", x.s[i]);
 97     return out;
 98 }
 99 
100 int main(void)        //URAL 1036 Lucky Tickets
101 {
102     //freopen ("W.in", "r", stdin);
103 
104     int n, s;
105     while (scanf ("%d%d", &n, &s) == 2)
106     {
107         if (s & 1)    {puts ("0");    continue;}
108 
109         dp[0][0] = 1;
110         int cur = 0;
111         for (int i=1; i<=n; ++i)
112         {
113             for (int j=0; j<=s/2; ++j)    dp[cur^1][j] = 0;    
114             for (int j=0; j<=9; ++j)
115             {
116                 for (int k=0; k+j<=s/2; ++k)
117                     dp[cur^1][k+j] = dp[cur^1][k+j] + dp[cur][k];
118             }
119             cur ^= 1;
120         }
121 
122         cout << dp[cur][s/2] * dp[cur][s/2] << endl;
123     }
124 
125     return 0;
126 }

 

posted @ 2015-05-11 21:06  Running_Time  阅读(241)  评论(0编辑  收藏  举报