zoukankan      html  css  js  c++  java
  • hdu 4427 Math Magic

           一个长了一张数学脸的dp!!dp[ i ][ s ][ t ] 表示第 i 个数,sum为 s ,lcm下标为 t 时的个数。显然,一个数的因子的lcm还是这个数的因子,所以我们的第三维用因子下标代替lcm,可以有效的减少枚举量。

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<cstdio>
    #include<cmath>
    #include<set>
    #define LL long long
    #define CLR(a, b) memset(a, b, sizeof(a))
    using namespace std;
    
    
    const int N = 1010;
    const int MOD = 1e9 + 7;
    
    
    int k, num, m;
    int dp[2][N][40];
    int ok[N], f[N][N];
    
    
    int gcd(int a, int b)
    {
        return b ? gcd(b, a % b) : a;
    }
    
    
    int lcm(int a, int b)
    {
        return a / gcd(a, b) * b;
    }
    
    
    int main()
    {
        //freopen("input.txt", "r", stdin);
        int n, i, j, s, t,  tmd = 0;
        while(scanf("%d%d%d", &n, &m, &k) != EOF)
        {
            CLR(dp, 0);num = 0;
            for(i = 1; i <= m; i ++)
            {
                if(m % i == 0) ok[num ++] = i;
            }//num不超过32
            for(i = 0; i < num; i ++)
            {
                for(j = 0; j < num; j ++)
                {
                    t = lcm(ok[i], ok[j]);
                    for(s = 0; s < num; s ++)
                    {
                        if(ok[s] == t)
                        {
                            f[i][j] = s;
                            break;
                        }
                    }
                }
            }
            for(j = 0; j < num; j ++)
            {
                dp[0][ok[j]][j] = 1;
            }
            for(i = 1; i < k; i ++)
            {
                for(s = 0; s <= n; s ++)//一定记得初始化
                {
                    for(t = 0; t < num; t ++)
                    {
                        dp[i & 1][s][t] = 0;
                    }
                }
                for(j = 0; j < num; j ++)
                {
                    for(s = i; s <= n - (k - i - 1) - ok[j]; s ++)
                    {
                        for(t = 0; t < num; t ++)
                        {
                            dp[i&1][s+ok[j]][f[t][j]]= (dp[i&1][s+ok[j]][f[t][j]]+dp[1-(i&1)][s][t]) % MOD;
                        }
                    }
                }
            }
            printf("%d
    ", dp[(k - 1) & 1][n][num - 1]);
        }
        return 0;
    }
    


     

  • 相关阅读:
    Linux提供两个格式化错误信息的函数
    warning: incompatible implicit declaration of built-in function ‘exit’
    RDMA的ibv_post_send() 函数
    (C语言)结构体成员的引用->(箭头)和 .(点)
    bcopy函数
    bzero函数
    利用GCC编译器生成动态链接库和静态链接库
    GCC编译器编译链接
    结构体类型定义(C语言)
    C语言编译链接
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3339668.html
Copyright © 2011-2022 走看看