Math Magic(完全背包)
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(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
Hint
The first test case: the only solution is (2, 2).
The second test case: the solution are (1, 2) and (2, 1).
题意:
给出n,m,k,问k个数的和为n,最小公倍数为m的情况有几种
思路:
因为最小公倍数为m,可以知道这些数必然是m的因子,那么我们只需要选出这所有的因子,拿这些因子来背包就可以了
dp[now][i][j]表示当前状态下,和为i,最小公倍数为j的解的个数。递推K次就出答案了。
注意需要优化!!!
详见代码
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define mod 1000000007 int num[];
int dp[][][];
int LCM[][]; int gcd(int a,int b)//最大公约数
{
if(b==) return a;
return gcd(b,a%b);
} int lcm(int a,int b)//最小公倍数
{
return (a*b/gcd(a,b));
} int main()
{
int n,m,k;
int i,j;
for(i=;i<=;i++)//预处理,前1000的最小公倍数
{
for(j=;j<=;j++)
{
LCM[i][j]=lcm(i,j);
}
}
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
int cnt=;
//因为最小公倍数m已知,所以Ai必定是他的因子
for(i=;i<=m;i++)
{
if(m%i==)
num[cnt++]=i;
} //dp[now][i][j]now表示当前状态下,和为i,最小公倍数为j的解的个数。递推K次就出答案了。
int now=;
//memset(dp[nom],0,sizeof(dp[nom]));
for(i=;i<=n;i++)
{
for(j=;j<cnt;j++)
{
//初始化,和为i,最小公倍数是num[j]的
dp[now][i][num[j]]=;
}
}
dp[][][]=; for(int t=;t<=k;t++)
{
now^=;
for(i=;i<=n;i++)
{
for(j=;j<cnt;j++)
{
dp[now][i][num[j]]=;
}
} for(i=t-;i<=n;i++)
{
for(j=;j<cnt;j++)
{
if(dp[now^][i][num[j]]==)continue;
for(int p=;p<cnt;p++)
{
int x=i+num[p];
int y=LCM[num[j]][num[p]];
if(x>n||m%y!=) continue;
dp[now][x][y]+=dp[now^][i][num[j]];
dp[now][x][y]%=mod;
}
}
}
}
printf("%d\n",dp[now][n][m]);
}
return ;
}
Math Magic(完全背包)的更多相关文章
- ZOJ3662:Math Magic(全然背包)
Yesterday, my teacher taught us about math: +, -, *, /, GCD, LCM... As you know, LCM (Least common m ...
- UVALive 6073 Math Magic
6073 Math MagicYesterday, my teacher taught us about m ...
- ZOJ-3662 Math Magic 背包DP
这题不错,可惜我还是太弱了,没想到qwq. 看了网上大佬题解之后写的,对比了一下代码,好像我写的还是挺简洁的(逃,只是吞行比较多). 因为直接用lcm的值做下标会超时,所以我们观察发现可以组成lcm为 ...
- [ZOJ 3662] Math Magic (动态规划+状态压缩)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3662 之前写过这道题,结果被康神吐槽说代码写的挫. 的确,那时候 ...
- DZY Loves Math II:多重背包dp+组合数
Description Input 第一行,两个正整数 S 和 q,q 表示询问数量.接下来 q 行,每行一个正整数 n. Output 输出共 q 行,分别为每个询问的答案. Sample Inpu ...
- Aizu 2155 Magic Slayer 背包DP
这是上上次对抗赛的题目了 其实现在发现整个代码从头到尾,都是用了背包,怪我们背包没深入学好. 比赛的时候,聪哥提出的一种思路是,预处理一下,背包出 ALL攻击 和 single攻击的 血量对应的最小花 ...
- DP(优化) UVALive 6073 Math Magic
/************************************************ * Author :Running_Time * Created Time :2015/10/28 ...
- hdu 4427 Math Magic DP
思路: dp[i][j][k]表示满足前i个数,和为j,lcm为k的数目. 设a为解的第i+1个数. 那么状态转移就为 dp[i+1][j+a][lcm(a,k)]+=dp[i][j][k]. 但是由 ...
- hdu 4427 Math Magic
一个长了一张数学脸的dp!!dp[ i ][ s ][ t ] 表示第 i 个数,sum为 s ,lcm下标为 t 时的个数.显然,一个数的因子的lcm还是这个数的因子,所以我们的第三维用因子下标代替 ...
随机推荐
- MVVM 简化的Messager类
看MVVMLight的Messager源码,自己实现了一个简单的Messager类. Messager类可以在MVVM中,实现View与VM.VM与VM.View与View的通信. public cl ...
- ASP.NET MVC 项目设置,移除多余的响应头,woff,woff2 字体文件请求处理
移除 X-AspNetMvc-Version 在 Global.asax 的 Application_Start添加代码 MvcHandler.DisableMvcResponseHeader = t ...
- 在windows10上创建ASP.NET mvc5+Memcached服务
感谢两位两位大佬: https://blog.csdn.net/l1028386804/article/details/61417166 https://www.cnblogs.com/running ...
- 「PKUSC2018」最大前缀和(状压dp)
前言 考试被\(hyj\)吊着打... Solution 考虑一下如果前缀和如果在某一个位置的后面的任意一个前缀和都<=0,肯定这就是最大的. 然后这样子就考虑左右两边的状压dp,然后就好了. ...
- Java-String类型的参数传递问题
刚才看见一个兄弟在为Java的String传值/传引用问题困惑,翻箱倒柜找到了这篇我很久以前写的文章,发在这里,希望能对迷惑的朋友有些帮助. 提要:本文从实现原理的角度上阐述和剖析了:在Java语言中 ...
- 564. Find the Closest Palindrome
Given an integer n, find the closest integer (not including itself), which is a palindrome. The 'clo ...
- Python基础 --函数的参数
定义函数的时候,我们把参数的名字和位置确定下来,函数的接口定义就完成了.对于函数的调用者来说,只需要知道如何传递正确的参数,以及函数将返回什么样的值就够了,函数内部的复杂逻辑被封装起来,调用者无需了解 ...
- 分组,命名分组,url的命名和反向解析
1.位置分组 匹配到参数,按照位置参数的方式传递给视图函数 视图函数需要定义形参接收变量 1.写在url里面的: # 删除 url(r'^del_class/(\d+)',views.del_clas ...
- Swift5 语言参考(三) 类型
在Swift中,有两种类型:命名类型和复合类型.一个名为类型是当它的定义可以给出一个特定名称的类型.命名类型包括类,结构,枚举和协议.例如,名为的用户定义类的实例MyClass具有该类型MyClass ...
- nginx官方文档 之 http负载均衡 学习笔记
一.负载均衡 算法 大致可以分两类: (1)不能保证用户的每一次请求都通过负载均衡到达同一服务器. (2)可保证用户的每一次请求都通过负载均衡到达同一服务器. 第二类的应用场景: 1.如果服务器有缓存 ...