题意:

告诉你n,m,k。

让你构造k 个数, 使得他们的和为n , 最小公倍数是m, 求方案数?

思路:

本以为是一个数学, 是一个水dp。

我们直接按照他描述的建立状态。

令 dp[i][j][k] , 表示 目前选了i 个数, 和为j , 最小公倍数是k 的方案数。

那么转移方程就很好写了   dp[i+1][j + a][lcm(a, k)] += dp[i][j][k].

但是得优化一些地方。

1.首先空间上  , 这样是爆内存的,  把第一维改成滚动数组就行了。

第二个 , 时间上优化。

转移时候你得枚举上一个数是啥, 这一个数是啥 , 这样1000的方了。

我们知道 ,假如k 个数的最小公倍数是m 的话 , 那么这k个数都是m 的因子。

2.那这样就好办了。 我们先处理m 的因子数量(最多不超过50).

然后枚举因子进行转移就好了。  这就成了50的方了。

3.另外还可以加入一些小的优化。

因为转移到m 只需要因子,  那么不如把因子离散化一下。

这样内存就开到了 dp[2][1000][50].

4. 在一点就是 lcm 时候也比较慢, 不如预处理出来所有因子的lcm。 这样olog 变成了 o1

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;int n, m, k;const int mod = 1000000000 + 7;long long dp[2][1007][50];int gcd(int a,int b){return !b ? a :gcd(b, a%b);
}int lcm(int a,int b){return a*b / gcd(a,b);
}int LCM[1007][1007];int fac[1007];
int cnt = 0;void add(long long& ans, long long x){ans += x;if (ans >= mod) ans -= mod;}
int pos[1007];
int main(){while(~scanf("%d %d %d",&n, &m, &k)){for (int i = 0; i <= n; ++i){for (int j = 0; j < 50; ++j){dp[0][i][j] = 0;}}cnt = 0;for (int i = 1; i <= m; ++i){if (m % i == 0) {fac[cnt++] = i;pos[i] = cnt-1;dp[0][i][pos[i] ] = 1;}}for (int i = 0; i < cnt; ++i){for (int j = 0; j < cnt; ++j){LCM[i][j] = lcm(fac[i], fac[j]);}}for (int i = 1; i < k; ++i){int second = (i & 1);int first = second ^ 1;for (int j = 0; j <= n; ++j){for (int o = 0; o < 50; ++o){dp[second][j][o] = 0LL;}}for (int j = 0; j <= n; ++j){for (int l = 0; l < cnt; ++l){int f = fac[l];if (dp[first][j][pos[f] ]){for (int  m = 0; m < cnt; ++m){int f2 = fac[m];if (j + f2 <= n)add(dp[second][j + f2][pos[LCM[l][m]] ] , dp[first][j][pos[f] ]);}}}}}printf("%I64d\n", dp[!(k & 1) ][n][pos[m] ]);}return 0;
}

Math Magic

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2133    Accepted Submission(s): 709

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
Recommend
zhuyuanchen520   |   We have carefully selected several similar problems for you:  6032 6031 6030 6029 6028 

Statistic | Submit | Discuss | Note

HDU 4427 Math Magic (2012长春-dp )相关推荐

  1. HDU 1520 Anniversary party(树形dp)

    HDU 1520 Anniversary party(树形dp) 树形dp第一题!!! 题意很清晰,思路也很明确.很容易找到根节点,即最大的boss,通过根节点向下dp. 状态转移方程: int to ...

  2. HDU 3001 三进制状压DP

    HDU 3001 三进制状压DP N个城市,M条道路,每条道路有其经过的代价,每一个城市最多能够到达两次,求走全然部城市最小代价,起点随意. 三进制状压.存储每一个状态下每一个城市经过的次数. 转移方 ...

  3. hdu 3401 Trade(单调队列优化dp)

    hdu 3401 Trade(单调队列优化dp) 题意:lxhgww喜欢炒股票,他可以在第i天买入或者卖出若干张股票(一天只能买或者卖),两个交易日之间至少相隔w天,问他t天后最多能赚多少. 解题思路 ...

  4. hdu 4283 You Are the One ( dp 2012 ACM/ICPC Asia Regional Tianjin Online )

    http://acm.hdu.edu.cn/showproblem.php?pid=4283 题意: The TV shows such as You Are the One has been ver ...

  5. hdu 5435 A serious math problem(数位dp)

    题目链接:hdu 5435 A serious math problem 裸的数位dp. #include <cstdio> #include <cstring> #inclu ...

  6. DP(优化) UVALive 6073 Math Magic

    /************************************************ * Author :Running_Time * Created Time :2015/10/28 ...

  7. HDU -- 2084 数塔(简单DP)

    HDU -- 2084  数塔 题意: 自上而下,选择一条累计和最大的路径 分析: 顶点只与左右两个子节点相关,且子节点路径的选择与顶点无关(无后效性) 状态dp[i][j]:表示(i,j)点向下得到 ...

  8. hdu 3183 A Magic Lamp (rmq)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3183 #include <stdio.h> #include <stdlib.h&g ...

  9. HDU 5729 Rigid Frameworks(连通性DP)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5729 [题目大意] 给出一个n*m的方格框,可以在单位矩形中添加两种对角线的线,使得其变得稳定,问 ...

  10. hdu 4778 Gems Fight! 状压dp

    转自wdd :http://blog.csdn.net/u010535824/article/details/38540835 题目链接:hdu 4778 状压DP 用DP[i]表示从i状态选到结束得 ...

最新文章

  1. 清华成立视觉智能研究中心,邓志东任中心主任
  2. python上下文管理器with
  3. python之拆包与装包
  4. redis作为mysql的缓存服务器(读写分离)
  5. 【STM32】系统配置控制器相关函数和类型
  6. Spring JSF集成
  7. 阿里云前端周刊 - 第 33 期
  8. center os php,Center OS 7 Apache安装配置
  9. java sun包无法引用_关于java包的问题,自己创建一个包,里面放了源文件,却包外无法引用:具体见问题补充...
  10. day8--pandas
  11. python编程实例
  12. 冲向星际的下一代互联网协议IPFS
  13. 1496.数括号法求广义表深度
  14. 西瓜视频4K修复技术还原经典,为内容创新打开新思路
  15. 创业公司中运营人员的典型一天是怎么度过的?
  16. 本题要求编写程序,计算序列 1 + 1/2 + 1/3 + ... 的前N项之和。
  17. linux怎么做bt种子文件,linux 制作BT种子并获取BT种子信息
  18. 锁存器Latch和触发器Flip-flop的区别
  19. 交通规划——基于TransCAD的线性参照和动态分段流程实现
  20. MATLAB算法实战应用案例精讲-【数据分析】核密度估计KDE(附matlab、R语言和python代码实现)

热门文章

  1. 21个奇葩注释,程序员看了都点赞
  2. Empathy Map:让团队移情到用户的奥秘
  3. 并发编程之四:并发之共享问题、线程安全、synchronized关键字
  4. 小火狐进化_神奇宝贝:最强和最弱的御三家属于哪个世代?当然是这两代
  5. Stm32学习(基于HAL库)
  6. 力扣刷题 DAY_88 贪心
  7. 关于TFP.STS的一个Bug(GPU内存爆掉,无法做预测)
  8. java 调用 yed 绘制 流程图_用 yEd Graph Editor 绘制流程图(2)
  9. Elastic:开发者上手指南
  10. android桌面 vulkan,Vulkan 设计指南