您的位置:首页 > 其它

递归---NYOJ-176 整数划分(二)和NYOJ-279队花的烦恼二

2014-10-30 16:59 190 查看
这道题目的递归思想和第一个题差不多, 主要思想是:func(n, m)的作用是将n划分为m个。

1. 如果n < m 的时候肯定是不能划分的,所以就返回0

2. 如果m = 1 或者 n = m 的时候,就一种划分方式

3. 如果n > m 的时候, 分为两种情况,一个是划分数中含有1, 一个是不含1, 所以含有1 的个数为func(n - 1, m - 1),意思就是从n去掉1,然后再划分m - 1个, 下面就是不含1的,

func(n - m, m), 这个式子的意思为, 先取出m个1来, 这样的话再将剩下的数,也就是n-m继续划分m个, 然后再把n - m个1加上去,肯定都是大于1的。所以式子为func(n - 1, m -1) + func(n - m, m);

代码如下(递归):

#include <stdio.h>

int func(int n, int m)
{
if(n < m)//n < m的时候肯定不能分, 所以返回0
return 0;
if(m == 1 || n == m)
return 1;
else//此步是含1和不含1
return func(n - 1, m - 1) + func(n - m, m);
}
int main()
{
int t, n, m;
scanf("%d", &t);
for(int i = 0; i < t; i++)
{
scanf("%d %d", &n, &m);
printf("%d\n", func(n, m));
}

return 0;
}


递推式已经出来了,所以可以用dp来做,其中数组dp
[m]的值就代表n 划分 m 份时的数量, 也就是题目让求的拆分方法的数目,第一层for循环是从1-110个数的划分是多少,第二层是每个数的对应j个拆分方法的数目是多少, 所以最后找n 拆成m 个方法的数目就是dp
[m];

代码如下(dp):

#include <stdio.h>
#include <string.h>

const int MAX = 110;
int main()
{
int a[MAX][MAX];
memset(a, 0, sizeof(a));
a[1][1] = 1;
for(int i = 2; i < MAX; i++)
{
for(int j = 1; j <= i; j++)
a[i][j] = a[i - 1][j - 1] + a[i - j][j];
}
int t1, t2, t;
scanf("%d", &t);
while(t--)
{
scanf("%d %d", &t1, &t2);
printf("%d\n", a[t1][t2]);
}
return 0;
}


题目279就不能用递归的方法来做了, 毕竟数据比这个大了,只能用第二种方法来做了。只要把第二种方法的MAX改一下就行了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: