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(1e9 + 7).

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

Sample Input

4 2 2
3 2 2

Sample Output

1
2


题意:
给出n,m,k,问k个数的和为n。最小公倍数为m的情况有几种

思路:
由于最小公倍数为m,能够知道这些数必定是m的因子,那么我们仅仅须要选出这全部的因子,拿这些因子来背包就能够了
dp[i][j][k]表示放了i个数,和为j。公倍数为k的情况有几种
可是又问题。首先的问题内存,直接存明显爆内存。那么我们须要优化
1.由于我如今放第i个数,必定是依据放好的i-1个数来计算的。我们仅仅须要用滚动数组来解决就可以
2.对于公倍数,必定不能超过m,而我全部这些m的因子中的数字,不管选哪些,选多少,他们的最小公倍数依旧是这些因子之中的,那么我们能够进行离散化
解决好了之后就是全然背包的问题了


#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <math.h>
using namespace std; const int mod = 1e9+7; int dp[2][1005][105];
int a[1005],len,pos[1005];
int n,m,k;
int hash[1005][1005]; int gcd(int a,int b)
{
return b==0? a:gcd(b,a%b);
}
int lcm(int a,int b)
{
return a/gcd(a,b)*b;
} int main()
{
int i,j,x,y;
for(i = 1; i<=1000; i++)//预处理最小公倍数
{
for(j = 1; j<=1000; j++)
hash[i][j] = lcm(i,j);
}
while(~scanf("%d%d%d",&n,&m,&k))
{
len = 0;
memset(pos,-1,sizeof(pos));
for(i = 1; i<=m; i++)
{
if(m%i==0)
{
a[len] = i;
pos[i] = len++;//离散化
}
}
memset(dp[0],-1,sizeof(dp[0]));
dp[0][0][0] = 1;
for(i = 1; i<=k; i++)
{
memset(dp[i%2],-1,sizeof(dp[i%2]));
for(j = i-1; j<=n; j++)//由于最小必定放1,而我前面已经放了i-1个数了。前面的和最少必定是i-1
{
for(x = 0; x<len; x++)//枚举前面数字的公倍数
{
if(dp[(i+1)%2][j][x]==-1)
continue;
for(y = 0; y<len && (a[y]+j)<=n; y++)//枚举这一位放哪些数
{
int r = hash[a[y]][a[x]];
int s = j+a[y];
if(pos[r]!=-1 && r<=m)
{
r = pos[r];
if(dp[i%2][s][r] == -1) dp[i%2][s][r] = 0;
dp[i%2][s][r]+=dp[(i+1)%2][j][x];
dp[i%2][s][r]%=mod;
}
}
}
}
}
if(dp[k%2][n][pos[m]]==-1)
printf("0\n");
else
printf("%d\n",dp[k%2][n][pos[m]]);
} return 0;
}

ZOJ3662:Math Magic(全然背包)的更多相关文章

  1. ZOJ-3662 Math Magic 背包DP

    这题不错,可惜我还是太弱了,没想到qwq. 看了网上大佬题解之后写的,对比了一下代码,好像我写的还是挺简洁的(逃,只是吞行比较多). 因为直接用lcm的值做下标会超时,所以我们观察发现可以组成lcm为 ...

  2. Math Magic(完全背包)

    Math Magic Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Sta ...

  3. hdu(1114)——Piggy-Bank(全然背包)

    唔..近期在练基础dp 这道题挺简单的(haha).可是我仅仅想说这里得注意一个细节. 首先题意: 有T组例子,然后给出储蓄罐的起始重量E,结束重量F(也就是当它里面存满了零钱的时候).然后给你一个数 ...

  4. UVALive 6073 Math Magic

                                                  6073 Math MagicYesterday, my teacher taught us about m ...

  5. HDU 1248 寒冰王座(全然背包:入门题)

    HDU 1248 寒冰王座(全然背包:入门题) http://acm.hdu.edu.cn/showproblem.php?pid=1248 题意: 不死族的巫妖王发工资拉,死亡骑士拿到一张N元的钞票 ...

  6. HDU 4508 湫湫系列故事——减肥记I(全然背包)

    HDU 4508 湫湫系列故事--减肥记I(全然背包) http://acm.hdu.edu.cn/showproblem.php?pid=4508 题意: 有n种食物, 每种食物吃了能获得val[i ...

  7. A_全然背包

    /* copyright: Grant Yuan algorithm: 全然背包 time : 2014.7.18 __________________________________________ ...

  8. nyist oj 311 全然背包 (动态规划经典题)

    全然背包 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描写叙述 直接说题意,全然背包定义有N种物品和一个容量为V的背包.每种物品都有无限件可用.第i种物品的体积是c,价值是 ...

  9. HDU 1114 Piggy-Bank 全然背包

    Piggy-Bank Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit S ...

随机推荐

  1. select 修改选中时候的默认默认样式 outline:none 把系统的线关了 然后自己再border一下

    chrome 查看样式的时候默认没有 focus的样式,可以把选择器开开select 修改选中时候的默认默认样式 outline:none 把系统的线关了 然后自己再border一下input:foc ...

  2. day02 python函数基础

    '''''''''列表: 定义: 在[]内,可以存放多个任意类型的值, 并以逗号隔开. 一般用于存放学生的爱好,课堂的周期等等...'''# 定义一个学生列表,可存放多个学生# list(['钱垚', ...

  3. adb 设备命令

    一.adb 设备命令1.查看机型时,可以使用以下命令$ adb shell getprop ro.product.model 2.如果我们忘记具体系统属性的名字$ adb shell getprop ...

  4. windows远程桌面链接“发生身份验证错误。要求的函数不受支持”

    解决办法: 开始菜单->运行gpedit.msc  打开配置项:计算机配置>管理模板>系统>凭据分配>加密Oracle修正 选择启用并选择易受攻击,配置保存后即可解决问题 ...

  5. C#语言中循环分类总结

    C#语言中,循环主要分为4种,分别是:while循环.do while循环.for循环.foeach循环.下面我将分类对循环语句总结. 1.while循环: 如果循环条件为真,则执行循环体:执行完循环 ...

  6. 零基础入门学习Python(22)--函数:递归是神马

    知识点 递归是神马? 递归是属于算法的范畴. 递归就是函数调用自身的一种行为. >>> def g(): return g() >>> g() Traceback ...

  7. C语言学习8

    计算某日是该年的第几天 编写一个计算天数的程序,用户从键盘输入年.月.日,在屏幕中输出此日期是该年的第几天. /******************************************** ...

  8. 洛谷 2187 小Z的笔记

    [题解] DP.  设f[i]表示前i个字母,保留第i个字母,最多可以保留多少个字母:设g[i]为当前字母为i的位置对应的f的最大值. 转移方程就是f[i]=max(f[i], g[j]+1) (j与 ...

  9. C51 独立按键 个人笔记

    独立按键类似于一个开关,按下时开关闭合 防抖 硬件防抖 软件防抖 通过延时,滤掉抖动的部分 电路图 普中科技的开发板,独立按键电路图如下 判断按键按下 因此判断是否按下开关的方法是看引脚是否为低电平( ...

  10. jQuery_计算器实例

    知识点: fadeIn()---计算器界面载入淡入效果 hover()---鼠标移入移出某个元素时触发的事件 click()---鼠标单击事件 css()---对元素样式的操作 val()---获取表 ...