HDU 4427 Math Magic(三维dp)

题目大意:给你三个数n,m,k。表示有k个数,他们的和为n,k个数的最小公倍数是m。让你求出符合这个条件的k个数的序列有多少种。

一看以为是个数论题,还尝试这各种分解m,然后进行组合数求情况。但是组合出来的数没法做减法啊。。。

结果是道dp题目。i,j,k表示到了第i个数此时和为j,最小公倍数为k。已经有了多少种组合方法了,直接向后推就可以了啊。数组太大开不开啊,滚动一下就可以了啊。

Math Magic

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 1321    Accepted Submission(s): 469

Problem Description

Yesterday, my teacher taught us about math: +, -, *, /, GCD, LCM... As you know, LCM (Least common multiple) of two positive numbers can be solved easily because of a * b = GCD (a, b) * LCM (a, b).

In class, I raised a new idea: “how to calculate the LCM of K numbers”. It‘s also an easy problem indeed, which only cost me 1 minute to solve it. I raised my hand and told teacher about my outstanding algorithm. Teacher just smiled and smiled...

After class, my teacher gave me a new problem and he wanted me solve it in 1 minute, too.

If we know three parameters N, M, K, and two equations:

1. SUM (A1, A2, ..., Ai, Ai+1,..., AK) = N

2. LCM (A1, A2, ..., Ai, Ai+1,..., AK) = M

Can you calculate how many kinds of solutions are there for Ai (Ai are all positive numbers).

I began to roll cold sweat but teacher just smiled and smiled.

Can you solve this problem in 1 minute?

Input

There are multiple test cases.

Each test case contains three integers N, M, K. (1 <= N, M <= 1,000, 1 <= K <= 100)

Output

For each test case, output an integer indicating the number of solution modulo 1,000,000,007(109 + 7).

You can get more details in the sample and hint below.

Sample Input

4 2 2
3 2 2

Sample Output

1
2

Hint

The first test case: the only solution is (2, 2).
The second test case: the solution are (1, 2) and (2, 1).

Source

2012 Asia ChangChun Regional Contest

#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <time.h>
#include <stack>
#include <map>
#include <set>
#define eps 1e-8
#define M 1000100
///#define LL long long
#define LL __int64
#define INF 0x3f3f3f
#define PI 3.1415926535898
#define mod 1000000007

using namespace std;

const int maxn = 1010;

int dp[2][maxn][maxn];
int lcm[maxn][maxn];
int num[maxn];

int LCM(int x, int y)
{
    return (x*y)/(__gcd(x, y));
}

void init()
{
    for(int i = 1; i <= 1000; i++)
        for(int j = 1; j <= 1000; j++) lcm[i][j] = LCM(i, j);
}

int main()
{
    int n, m, k;
    init();
    while(~scanf("%d %d %d", &n, &m, &k))
    {
        int ans = 0;
        for(int i = 1; i <= m; i++)
            if(!(m%i)) num[ans++] = i;
        for(int i = 0; i <= n; i++)
            for(int j = 0; j < ans; j++) dp[0][i][num[j]] = 0;
        dp[0][0][1] = 1;
        int now = 0;
        for(int i = 1; i <= k; i++)
        {
            now ^= 1;
            for(int si = 0; si <= n; si++)
                for(int sj = 0; sj < ans; sj++) dp[now][si][num[sj]] = 0;
            for(int si = i-1; si <= n; si++)
            {
                for(int sj = 0; sj < ans; sj++)
                {
                    if(!dp[now^1][si][num[sj]]) continue;
                    for(int sx = 0; sx < ans; sx++)
                    {
                        int x = si+num[sx];
                        int y = lcm[num[sj]][num[sx]];
                        if(x > n || m%y) continue;
                        dp[now][x][y] += dp[now^1][si][num[sj]];
                        dp[now][x][y] %= mod;
                    }
                }
            }
        }
        printf("%d\n",dp[now][n][m]%mod);
    }
    return 0;
}
时间: 2024-10-08 10:54:28

HDU 4427 Math Magic(三维dp)的相关文章

HDU 4427 Math Magic (2012年长春现场赛H题)

1.题目描述:点击打开链接 2.解题思路:本题要求寻找k个正整数,它们的和恰好是N,它们的LCM恰好是M的解的个数.可以设置一个三维的dp来解决.用dp(i,j,k)表示选择i个数,它们的和恰好是j,它们的LCM恰好是k的个数.那么答案就是dp(k,n,m).不过这里介绍一种利用状态压缩思想求解的方法. 通过题意可以发现,N,M的范围都比较小,不超过1000,而1000之内的所有数的不同素因子的种类数目不超过4个,这是因为2*3*5*7<1000,而2*3*5*7*11>1000.考虑到素因子

HDU 4433 locker(三维dp)

这题不太好想啊....我以为是记忆化搜索但是感觉最后的状态不好转移啊.别人都是用三维dp写的,感觉很巧啊. binshen写的:http://www.cnblogs.com/kuangbin/archive/2012/10/27/2742672.html 这题的意思就相当于是一个数字密码锁. 每次可以正向或者反向旋转连续的1-3个数字.求从现在状态转到目标状态需要的最少步数. 题目给了两个长度一样的由0-9组成的字符串.就相当于每次操作可以选择连续的1-3个数字加1或者减1.这不过这个加和减是循

UVALive 6073 Math Magic

                                              6073 Math MagicYesterday, my teacher taught us about math: +, -, *, /, GCD, LCM... As you know, LCM (Leastcommon multiple) of two positive numbers can be solved easily because of a ∗ b = GCD(a, b) ∗ LCM(a

HDU 4833 Best Financing (DP)

Best Financing Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 29    Accepted Submission(s): 3 Problem Description 小A想通过合理投资银行理财产品达到收益最大化.已知小A在未来一段时间中的收入情况,描述为两个长度为n的整数数组dates和earnings,表示在第dat

HDU 4518 ac自动机+数位dp

吉哥系列故事--最终数 Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 304    Accepted Submission(s): 102 Problem Description 在2012年腾讯编程马拉松比赛中,吉哥解决了一道关于斐波那契的题目,这让他非常高兴,也更加燃起了它对数学特别是斐波那契数的热爱.现在,它又在思考一个关于斐波那契

HDU 5234 Happy birthday --- 三维01背包

HDU 5234 题目大意:给定n,m,k,以及n*m(n行m列)个数,k为背包容量,从(1,1)开始只能往下走或往右走,求到达(m,n)时能获得的最大价值 解题思路:dp[i][j][k]表示在位置(i,j)有一个容量为k的背包所能获得的最大价值 决策:a[i][j]处的数是否选取 不选取: dp[i][j][k]= max(dp[i-1][j][k], dp[i][j-1][k]) 选取:首先要求k >=a[i][j],那么dp[i][j][k] = max(dp[i-1][j][k-w[i

hdu 4568 Hunter 最短路+dp

Hunter Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2014    Accepted Submission(s): 615 Problem Description One day, a hunter named James went to a mysterious area to find the treasures. Jame

HDU 4050 wolf5x (概率DP 求期望)

题意:有N个格子,1~N,起点在0,每个格子有一个状态(0,1,2,3),每次可以跨[a,b]步, 问走完N个格子需要步数的期望,每次尽量走小的步数,即尽量走a步,不能则走a+1,-- 状态0意味着你不能踏进对应的网格. 状态1意味着你可以??步入网格用你的左腿. 状态2意味着你可以??步入网格用你的右腿. 状态3意味着你可以进入网格用任何你的腿,而接下来的步骤中,您可以使用任何的腿;即你不需要遵循上述规则. 思路:借鉴了各路大神的思想理解了下. dp[i][j] :表示走到第 i 个格子在 j

Math Magic(完全背包)

Math Magic Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Status Description Yesterday, my teacher taught us about math: +, -, *, /, GCD, LCM... As you know, LCM (Least common multiple) of two positive numbers can b