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 }

 

你可能感兴趣的:(dp)