递推之种萝卜

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37220238/article/details/79943664

描述

一农夫挖了n个坑,准备种萝卜,n个坑排成一条直线,农夫认为如果连续m个坑都放入萝卜种子,那么就会影响萝卜的生长,所以某些坑中就不能放萝卜种子。

本题的任务是:对于给定的n和m,求不影响生长的种法的总数。

输入一行两个正整数n和m,之间用空格隔开

0≤n≤64 , 0≤m≤5输出一行一个正整数,表示正确种法的总数

样例输入

4 3

样例输出

13

 

提示

找呗0个坑只有不种一种情况;1个坑要看m的情况

 

解题思路

    很显然这道题要使用递推的方法来做。这道题的递推式算是比较难想到的,我认为在做这种递推时要分好情况。例如说这道种萝卜的题目分为三种情况如下:

1.n<m 

    当坑数小于影响萝卜生长连续坑数时,想一想是不是随便怎样种都行?那如何推出此时的种法数和之前的种法数的关系呢?OK,由于现在n<m的,所以有n-1<m。那当坑数为n-1,影响萝卜生长连续坑数为m时,是不是更加是随便种都行?设此时的种法为f(n-1)(m),好,现在求递推式的关键来了,看一下下面的图你就懂了

    当坑数为n-1影响萝卜生长连续坑数为m时,合理的种法为f(n-1)(m)当坑数为n影响萝卜生长连续坑数为m时,是不是就是在坑数为n-1加了一个第n个坑?第n个坑的情况为种与不种2种情况,那是不是

f(n)(m)=2* f(n-1)(m)呢?

2.m=n

    n=m时,也就是说坑数和影响萝卜生长连续坑数相等时,是不是就是把n个坑全中满这一种情况不行呀?此时我们的递推公式是不是在所有种法的基础上减去1就好了,即f(n)(m)=2* f(n-1)(m)-1;

3.n>m

    n>m时,也就是说坑数大于影响萝卜生长连续坑数时,这时的情况比较复杂。看一下下面的图和文字。

    假设现在n个坑,而且为合理种法,那其种法为2*f(n-1)(m);假设当增加1个坑之后如果这个第n+1个坑要种,后面刚好成了m个连续的坑,就成了不合理的种法。那这种不合理的种法应该有多少种呢?那是不是现在确定了m-1个连续的坑都要种萝卜,而前面n-m-1个坑肯定是为合理种法,有f(n-m-1)(m)种,所以此时不合理的种法应f(n-m-1)(m)种。那此时的合理种法应该为所有的种法减去不合理的种法f(n-m-1)(m),即f(n)(m)= 2*f(n-1)(m)- f(n-m-1)(m)

参考程序

#include<iostream>
using namespace std;
long long a[66][6];//数组要定义成long long型,要不然到最后会爆
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0;i<=n;i++)
        for(int j=0;j<=m;j++)
            if(i==0)a[i][j]=1;//0个坑只有不种一种情况
            else if(i<j)a[i][j]=2*a[i-1][j];//n<m:f(n)(m)=2* f(n-1)(m);
                else if(i==j)a[i][j]=2*a[i-1][j]-1;//n=m:f(n)(m)=2* f(n-1)(m)-1
                    else if(i>j)a[i][j]=2*a[i-1][j]-a[i-1-j][j];//n>m:f(n)(m)= 2*f(n-1)(m)- f(n-m-1)(m)
    cout<<a[n][m];
    return 0;
}

 

 

猜你喜欢

转载自blog.csdn.net/qq_37220238/article/details/79943664