题目

给出两个正整数N和M, N <= 100, M <= 50, 可以将N分解成若干个不相等的正整数A1, A2... Ak的和,且A1, A2 ... Ak的乘积为M的倍数。即 
N = A1 + A2 + ... + Ak; 
A1*A2*...Ak % M = 0; 
求可以有多少种分解方式? 
题目链接: divided product

分析

直接DFS搜索,DFS(cur_sum, cur_max_num, cur_product) 枚举出总和为N的,且各个数字不断增加的方案,然后判断他们的乘积是否等于M的倍数。实现复杂度为:(2^t, t 为几十的量级),显然不行; 
考虑动态规划来解决: 
    维护状态 dp[i][j][t] 表示 A1,A2...Ak的总和为i,且最大的数字Ak等于j,A1*A2..A*k的结果模M为t的分解方案总个数。 
则可以有递推公式:

  1. int tt = k*t%M;
  2. dp[i + k][k][tt] += dp[i][j][t];
  3. dp[i + k][k][tt] %= mod;

其中需要注意 边界条件 dp[i][i][i%M] = 1.

实现

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<string>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<algorithm>
using namespace std;
int dp[105][105][55];
int main(){
const int mod = 1000000007;
int n, m;
scanf("%d %d", &n, &m);
memset(dp, 0, sizeof(dp));
for (int i = 0; i <= n; i++){
for (int j = 0; j <= i; j++){
for (int k = j + 1; (k + i) <= n; k++){
for (int t = 0; t < m; t++){
if (i == 0)
dp[k][k][k%m] = 1;
else{
int tt = k*t%m;
dp[i + k][k][tt] += dp[i][j][t];
dp[i + k][k][tt] %= mod;
}
}
}
}
}
int result = 0;
for (int i = 1; i <= n; i++)
result = (result + dp[n][i][0]) % mod;
printf("%d\n", result);
return 0;
}

hiho1096_divided_product的更多相关文章

随机推荐

  1. Kernel启动时 驱动是如何加载的module_init,加载的次序如何;略见本文

    Init.h中有相关initcall的启动次序,在system.map中可看出具体的__initcall指针的前后次序 #define pure_initcall(fn) __define_initc ...

  2. hdu Interesting Fibonacci

    Interesting Fibonacci Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  3. IIS WebForm开发基础

    Winform是在客户电脑操作的. WebForm是客户机通过一个IP地址,到IIs服务器,再进行信息反馈,在非客户机上操作的. 一.WebForm 运行流程(1)需要访问数据库(aspx) 客户机打 ...

  4. MVC2.0==>MVC3.0

    总结出如下4个MVC3.0和2.0的重要区别. 1. @ 符号在 View 页面中的用法: C#代码以 @符号开头,例如 1 <h2>Name: @Model.Name</h2> ...

  5. 编写2个接口:InterfaceA和InterfaceB;在接口InterfaceA中有个方法void printCapitalLetter();在接口InterfaceB中有个方法void printLowercaseLetter();然 后写一个类Print实现接口InterfaceA和InterfaceB,最后再在主类E 的main方法中创建Print的对象并赋值,运行方法

    package lianxi; public interface InterfaceA { void printCapitalLetter(); } package lianxi; public in ...

  6. L0/L1/L2范数的联系与区别

    L0/L1/L2范数的联系与区别 标签(空格分隔): 机器学习 最近快被各大公司的笔试题淹没了,其中有一道题是从贝叶斯先验,优化等各个方面比较L0.L1.L2范数的联系与区别. L0范数 L0范数表示 ...

  7. [HDOJ5289]Assignment(RMQ,二分)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5289 题意:求满足区间内最大值和最小值差为k的区间个数. 预处理出区间的最值,枚举左端点,根据最值的单 ...

  8. [转]Linux下的暴力密码破解工具Hydra详解

    摘自:http://linzhibin824.blog.163.com/blog/static/735577102013144223127/ 这款暴力密码破解工具相当强大,支持几乎所有协议的在线密码破 ...

  9. apue和error

    在做进程环境测试的时候,测试demo中出现了apue.h,而标准库中没有这个头文件和其中的函数定义,经查找需要在/usr/include中添加apue.h和error.c.原型可以去这个网站查找.   ...

  10. Codeforces Round #243 (Div. 2) B(思维模拟题)

    http://codeforces.com/contest/426/problem/B B. Sereja and Mirroring time limit per test 1 second mem ...