拆数游戏dp

欢迎访问郑州大学程序设计在线评测系统(ZZUOJ)!  ZZUACM招新群号:562888278


问题4317--有趣的拆数游戏

4317: 有趣的拆数游戏

时间限制: 1 Sec  内存限制: 128 MB
提交: 28  解决: 8
[提交] [状态] [讨论版] [命题人:admin]

题目描述

        Zxy 特别喜欢数学,他看到过许多有趣的拆数题,比如:把一个数拆成两个质数的和或者将一个数拆成若干个数的和,使得它们的乘积最大,当然这些都是简单的的问题了,对于热爱算法竞赛并且足够优秀的你,当然不用解决这些简单的问题啦。

       现在zxy需要有一个拆数问题交给你。

       对于一个整数n,你可以将它拆成若干个数的和,例如
1: {1}
2: {1+1, 2}
3: {1+1+1, 1+2, 2+1, 3}
4: {1+1+1+1, 1+1+2, 1+2+1, 1+3, 2+1+1, 2+2, 3+1, 4}
注意:同样的集合元素顺序不同,我们也认为它们是不同的!
         zxy想要统计到底有多少种拆分整数n的方法,所以一个个写下所有的可能,zxy的队友孙刚来趁zxy不注意就把一些方案擦去了,zxy很生气但是又没有办法。他发现擦去的集合都有一些特点,就是这个集合的元素里面含有偶数。
例如对于1,2,3,4剩下的拆分方法是:
1: {1}
2: {1+1}
3: {1+1+1, 3}
4: {1+1+1+1, 1+3, 3+1}
    zxy突然灵机一闪,想知道对于一个整数n,不含有{m+i*k∣i=0,1,...}集合内元素的拆分方法共有多少个?

 

输入

第一行一个整数T(T<= 60),代表测试样例的数量
一个样例包括一行包含三个整数  n,m,k(  1<=n<=30,0<=m,k<30)

 

 

输出

T行,每行输出当前组数据拆分方法的数量
 

 

样例输入

3
10 0 2
15 1 4
28 3 7

 

样例输出

55
235
18848806

 

#include 
using namespace std;
const int maxn=31;
int dp[maxn];
int n,m,k,T;
bool check(int x)
{
	
	if((x-m)%k) return true;
	else return false;
}

int main()
{
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d%d",&n,&m,&k);
		memset(dp,0,sizeof(dp));
		dp[0]=1;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=i;j++){
				if(check(j)) dp[i]+=dp[i-j];
			}
		}
		printf("%d\n",dp[n]);
	}
	
	return 0;
}

 

你可能感兴趣的:(动态规划)