zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Java 下载网络资源
    Java11 ThreadLocal的remove()方法源码分析
    软件测试的术语SRS,HLD,LLD,BD,FD,DD意义
    2020年12月2日
    20201129
    2020年11月28日
    程序员的三门课
    中间件到底是个什么鬼东西?
    接口测试框架的形成过程
    一个字符到底等于多少字节
  • 原文地址:https://www.cnblogs.com/LyonLys/p/hdu_1223_Lyon.html
Copyright © 2011-2022 走看看