求一道动态规划题目的思路,没有思路Ing

flyinghawl 2010-06-05 04:50:27
描述

如上图所示,我们可以用不同数量的火柴排成0~9这10个数字。现在这个问题需要让聪明的你来计算一下,给你N根火柴,总共可以组合成多少个被M取余后结果是素数的数字。
注意,N根火柴都要用上,另外,除了0,其他数字均不能出现前导零。
输入
第一行有一个正整数T,表示有T组测试数据。
接下来T行每一行表示一组测试数据,每行包含空格隔开的两个正整数N和M。
其中:
T < =20,
N, M <=10000并且M*N<=1000000
输出
对于每一个测试数据,请输出一行,包含一个数,即结果对1000000007取模的值。
样例输入
4
4 15
20 4
6 10
6 20
样例输出
1
6982
1
2
...全文
134 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
fanster28_ 2010-06-05
  • 打赏
  • 举报
回复
dp[n][k]表示n跟火柴可以组合的数中模m余k的个数

dp[n+need[j]][k*10+j] += dp[n][k] 表示用need[j]跟火柴组成了j,填到n的末尾
n原来是123,现在就变为123*10+j = 123j

组合成123j的有多种方式,所以用+= 初始的时候都为0,然后初始化几个初始值即可
fanster28_ 2010-06-05
  • 打赏
  • 举报
回复
状态方程在代码中一目了然
#include <stdio.h>
#include <memory.h>

const int need[10] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6},mod = 1000000007,range = 10005;
bool isnp[range];
int dp[1010005];

inline void add(int &a,int b)
{
a+=b;
if (a>=mod) a-=mod;
}

int main()
{
int t, n, m, i, j, k, res;
isnp[0]=isnp[1]=true;
for (i=2; i<range; i++)
if (!isnp[i])
for (j=2*i;j<range;j+=i)
isnp[j]=true;
for(scanf("%d",&t); t; --t)
{
scanf("%d %d", &n, &m);
memset(dp, 0, sizeof(dp));
for (i = 1; i < 10; i++) //因为前导0不算dp[6][0]=0
dp[need[i] * m + (i % m)]++;
for (i = 0; i < n; i++)
for (j = 0; j < 10; j++) if (i + need[j] <= n)
for (k = 0; k < m; k++)
add(dp[(i + need[j]) * m + (k * 10 + j) % m],dp[i * m + k]);
for (i=res=0; i < m; i++) if (!isnp[i])
add(res,dp[n * m + i]);
printf("%d\n", res);
}
return 0;
}
qq120848369 2010-06-05
  • 打赏
  • 举报
回复
太智商了,随便看看就行了.
flyinghawl 2010-06-05
  • 打赏
  • 举报
回复
原题的地址:
http://poj.youdao.com/nanti3/C/

33,027

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧