zoukankan      html  css  js  c++  java
  • WHU 1568 Product (DP、逆元)

    题意:

          定义f(x) 为数x的所有数字的乘积.

          求满足f(k)=f(x)的不同的不含数字1的k的个数.

          x的长度小于50.

          不超过1000组数据.


    Solution:

          由于函数是乘积的形式,可以由质因子着手分析:

          数字的范围是1~9,1~9中只有2,3,5,7 四个质数,即f(x)可以表示为这四个质数的幂的乘积的形式.

          注意到x的长度小于50,那么质因子最多不超过150(50个8),这个时候似乎可以通过枚举4 6 8 9这四个因子的个数来,得到答案.因为5,7可以单独处理,2和3的个数可以通过4,6,8,9的个数求得.另外4的个数不超过75.而6,8,9的个数也不超过50.从时间复杂度上看是我们能够接受的.但是数据有1000组.这似乎迫使我们采用能够预处理一些我们需要的东西的算法.

         令f[k][i][j],为长度为k,含有i个2因子,j个3因子的数的个数.

         对于f[k+1],不过是在k的后面加了2~9这8个数,只要对每个数,更新对应的i,j就行了.

         这样我们可以先预处理足够大多的f[k][i][j],因为最多不过150个2因子,100个3因子,所以预处理到f[150][150][100]就够了.

         对于一组输入,统计2,3,5,7这四个因子的个数,利用多重排列的公式计算出答案,因为要对除法取模,所以要用到逆元.

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define LL long long
    using namespace std;
    const int MOD = 1000000007;
    int n, m;
    LL dp[160][160][160], f[200];
    int sum[5];
    char s[100];
    LL Quikpower (LL  Base, LL  Power) {
        LL  k = 1;
        while ( Power > 0) {
            if (Power & 1) k = (k * Base) % MOD;
            Base = (Base * Base) % MOD;
            Power >>= 1;
        }
        return k;
    }
    LL cnt (LL k, int m, int a, int b) {
        LL ans = k;
        for (int i = 1; i <= a + b; i++)
            ans = ans * (m + i) % MOD;
        ans = ans * Quikpower (f[a], MOD - 2) % MOD;
        ans = ans * Quikpower (f[b], MOD - 2) % MOD;
        return ans;
    }
    int main() {
        f[0] = 1;
        for (int i = 1; i <= 150; i++)
            f[i] = (f[i - 1] * i) % MOD;
        dp[0][0][0] = 1;
        for (int i = 0; i <= 150; i++)
            for (int s2 = 0; s2 <= 150; s2++)
                for (int s3 = 0; s3 <= 150; s3++) {
                    if (dp[i][s2][s3] == 0) continue;
                    dp[i + 1][s2 + 1][s3] = (dp[i + 1][s2 + 1][s3] + dp[i][s2][s3]) % MOD;//2
                    dp[i + 1][s2][s3 + 1] = (dp[i + 1][s2][s3 + 1] + dp[i][s2][s3]) % MOD; //3
                    dp[i + 1][s2 + 2][s3] = (dp[i + 1][s2 + 2][s3] + dp[i][s2][s3]) % MOD;//4
                    dp[i + 1][s2 + 1][s3 + 1] = (dp[i + 1][s2 + 1][s3 + 1] + dp[i][s2][s3]) % MOD; //6
                    dp[i + 1][s2 + 3][s3] = (dp[i + 1][s2 + 3][s3] + dp[i][s2][s3]) % MOD;//8
                    dp[i + 1][s2][s3 + 2] = (dp[i + 1][s2][s3 + 2] + dp[i][s2][s3]) % MOD; //9
                }
        while (scanf ("%d", &n) != EOF) {
            scanf ("%s", s);
            memset (sum, 0, sizeof sum);
            for (int i = 0; i < n; i++) {
                int k = s[i] - '0';
                if (k == 2 || k == 6 || k == 8) sum[0]++;
                if (k == 4 || k == 8) sum[0] += 2;
                if (k == 3 || k == 6) sum[1]++;
                if (k == 9) sum[1] += 2;
                if (k == 5) sum[2]++;
                if (k == 7) sum[3]++;
            }
            int m = sum[0] + sum[1];
            LL ans = 0;
            if (m + sum[2] + sum[3] != 0)
                for (int i = 0; i <= m; i++)
                    if (dp[i][sum[0]][sum[1]])
                        ans = (ans + cnt (dp[i][sum[0]][sum[1]], i, sum[2], sum[3]) ) % MOD;
            cout << ans << endl;
        }
    }
    View Code
  • 相关阅读:
    toj 1410. Euclid's Game 夜
    hdu 1404 Digital Deletions 夜
    hdu 1536 SNim 夜
    1180. Stone Game 夜
    hdu 1729 Stone Game 夜
    一个有价值的 Sharepoint WebPart 页签部件
    开始 MS Project & P3 E/C 探讨历程!
    cvccomplextype.3.2.2: Attribute 'singleton' is not allowed to appear in element 'bean
    启迪技术
    上传图片:
  • 原文地址:https://www.cnblogs.com/keam37/p/4448477.html
Copyright © 2011-2022 走看看