hdu 1223 Order Count

http://acm.hdu.edu.cn/showproblem.php?pid=1223

  dp递推求满足条件的不等式的个数。

  这里需要用到大数乘法,于是我就顺便打了一个大数的模板,重载了+和*运算符。

  递推的公式很简单,dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j] * j,其中i 是指共有i 个符号,j 是指将i 个符号分成j 份,dp得到种类的数目。然后dp[i][1~i]各项相加,就是最终的答案了。

代码如下:

View Code
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <cassert>
  5 #include <cmath>
  6 #include <algorithm>
  7 
  8 using namespace std;
  9 
 10 const int maxSize = 150;
 11 
 12 struct bigNum {
 13     char num[maxSize];
 14 };
 15 
 16 bigNum operator * (bigNum a, bigNum b) {
 17     int la = strlen(a.num);
 18     int lb = strlen(b.num);
 19     bigNum ret;
 20     int tmp[maxSize];
 21 
 22     for (int i = 0; i < la; i++) a.num[i] -= '0';
 23     for (int i = 0; i < lb; i++) b.num[i] -= '0';
 24     for (int i = 0, endi = la + lb; i <= endi; i++) tmp[i] = ret.num[i] = 0;
 25     for (int i = 0; i < la; i++) {
 26         int ti = la - 1 - i;
 27 
 28         for (int j = 0; j < lb; j++) {
 29             int tj = lb - 1 - j;
 30 
 31             tmp[i + j] += a.num[ti] * b.num[tj];
 32         }
 33     }
 34     for (int i = 0, endi = la + lb - 1; i < endi; i++) {
 35         tmp[i + 1] += tmp[i] / 10;
 36         ret.num[endi - i] = tmp[i] % 10 + '0';
 37     }
 38     ret.num[0] = tmp[la + lb - 2] / 10 + '0';
 39 
 40     if (ret.num[0] == '0') {
 41         for (int i = 1, endi = la + lb + 2; i < endi; i++) {
 42             ret.num[i - 1] = ret.num[i];
 43         }
 44     }
 45 
 46     return ret;
 47 }
 48 
 49 bigNum operator + (bigNum a, bigNum b) {
 50     int la = strlen(a.num);
 51     int lb = strlen(b.num);
 52     bigNum ret;
 53     int maxLen = max(la, lb);
 54     int minLen = min(la, lb);
 55 
 56     for (int i = 0; i <= maxLen + 1; i++) ret.num[i] = 0;
 57     for (int i = 0; i < minLen; i++) {
 58         ret.num[maxLen - i] += a.num[la - i - 1] + b.num[lb - i - 1] - '0';
 59         if (ret.num[maxLen - i] > '9') ret.num[maxLen - i - 1]++, ret.num[maxLen - i] -= 10;
 60     }
 61     if (maxLen == la) {
 62         for (int i = minLen; i < maxLen; i++) {
 63             ret.num[maxLen - i] += a.num[la - i - 1];
 64             if (ret.num[maxLen - i] > '9') ret.num[maxLen - i - 1]++, ret.num[maxLen - i] -= 10;
 65         }
 66     } else {
 67         for (int i = minLen; i < maxLen; i++) {
 68             ret.num[maxLen - i] += b.num[lb - i - 1];
 69             if (ret.num[maxLen - i] > '9') ret.num[maxLen - i - 1]++, ret.num[maxLen - i] -= 10;
 70         }
 71     }
 72     ret.num[0] += '0';
 73 
 74     if (ret.num[0] == '0') {
 75         for (int i = 1, endi = la + lb + 2; i < endi; i++) {
 76             ret.num[i - 1] = ret.num[i];
 77         }
 78     }
 79 
 80     return ret;
 81 
 82 }
 83 
 84 const int maxn = 52;
 85 bigNum dp[maxn][maxn];
 86 bigNum fac[maxn];
 87 
 88 char *con(int x) {
 89     int len = (int)log10((double)x) + 1;
 90     char *ret = new char[len + 1];
 91 
 92     for (int i = len - 1; i >= 0; i--) {
 93         ret[i] = x % 10 + '0';
 94         x /= 10;
 95     }
 96     ret[len] = 0;
 97 
 98     return ret;
 99 }
100 
101 void pre() {
102     strcpy(fac[0].num, "1");
103     for (int i = 1; i < maxn; i++){
104         bigNum tmp;
105         char *temp = con(i);
106 
107         strcpy(tmp.num, temp);
108         delete temp;
109         fac[i] = fac[i - 1] * tmp;
110     }
111     for (int i = 1; i < maxn; i++) {
112         strcpy(dp[i][1].num, "1");
113         strcpy(dp[i][i].num, "1");
114         for (int j = 2; j < i; j++) {
115             bigNum tmp;
116             char *temp = con(j);
117 
118             strcpy(tmp.num, temp);
119             delete temp;
120             dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j] * tmp;
121         }
122         strcpy(dp[i][0].num, "0");
123         for (int j = 1; j <= i; j++){
124             dp[i][0] = dp[i][0] + dp[i][j] * fac[j];
125         }
126 //printf("%s\n", dp[i][0].num);
127     }
128 }
129 
130 int main() {
131     pre();
132     int n, T;
133 
134     scanf("%d", &T);
135     while (T-- && ~scanf("%d", &n)){
136         printf("%s\n", dp[n][0].num);
137     }
138 
139     return 0;
140 }

 

——written by Lyon

转载于:https://www.cnblogs.com/LyonLys/archive/2012/09/22/hdu_1223_Lyon.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值