题目

给出两个正整数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. openmp在图像处理上面的运用

    // openmptest的测试程序 //   #include "stdafx.h"   void Test(int n){     for (int i=0;i<1000 ...

  2. Animation Play/Stop测试

    测试结果: 1.当切换不同动画播放,可以直接调用Play或者CrossFade.会立即切过去 2.当相同动画再次播放,又想打断重头再播,需要先调用Stop. anim.Play("Test1 ...

  3. isp和3a的联系与区别是什么?

    Willis Zen上善若水 2 人赞同 你说的这个问题,不是很多人能够回答的,我也只能把我知道的告诉你.isp 是image signal processing,用于图像处理,比如gamma调整,d ...

  4. CSU 1325: A very hard problem 中南月赛的一道题。

    1325: A very hard problem Time Limit: 3 Sec  Memory Limit: 160 MBSubmit: 203  Solved: 53[Submit][Sta ...

  5. 2016年11月4日 星期五 --出埃及记 Exodus 19:20

    2016年11月4日 星期五 --出埃及记 Exodus 19:20 The LORD descended to the top of Mount Sinai and called Moses to ...

  6. FCKeditor使用方法技术详解

    转载自 http://www.cnblogs.com/cchyao/archive/2010/07/01/1769204.html 1.概述 FCKeditor是目前最优秀的可见即可得网页编辑器之一, ...

  7. 我的android学习经历26

    ViewPager的使用 ViewPager就想微信或者qq的顶部的导航栏一样,滑动可以改变到不同的View或者Fragment 使用方法: 在布局文件中定义标签: android.support.v ...

  8. __declspec关键字详细用法

    __declspec关键字详细用法 __declspec用于指定所给定类型的实例的与Microsoft相关的存储方式.其它的有关存储方式的修饰符如static与extern等是C和C++语言的ANSI ...

  9. 【转载】C++知识库内容精选 尽览所有核心技术点

    原文:C++知识库内容精选 尽览所有核心技术点 C++知识库全新发布. 该知识库由C++领域专家.CSDN知名博客专家.资深程序员和项目经理安晓辉(@foruok)绘制C++知识图谱,@wangshu ...

  10. Lucky String

    Lucky String -- 微软笔试 标签(空格分隔): 算法 A string s is LUCKY if and only if the number of different charact ...