设f(n,m)为所求答案,则f(n,m)求得是:2^n,当m>n;2f(n-1,m) - f(n-m-1,m),当m<=n
首先,m>n的时候是2^n很好理解,所有2^n种放法均满足要求
然后就是m<=n的情况了。我们用递推的思维思考。对于f(n-1,m)种情况,在它们后面无论加1、加0都是可以作为一个等待确认的解的。这里就是2f(n-1,m)。但是,在后面加1的时候可能会因为前面的某些放法是以m-1个连续的核物质结尾,加上这个导致这个解无效。我们要考虑的就是要去掉这些解。这些解一共多少呢?因为它们仅以m-1个连续的核物质结尾,换句话说,它们必然是以011..1(m-1个1)结尾的。所以是f(n-m-1,m)种情况。两者相减就得到了f(n,m)的式子。
于是我们只要开一个数组来计算就可以了。
首先,m>n的时候是2^n很好理解,所有2^n种放法均满足要求
然后就是m<=n的情况了。我们用递推的思维思考。对于f(n-1,m)种情况,在它们后面无论加1、加0都是可以作为一个等待确认的解的。这里就是2f(n-1,m)。但是,在后面加1的时候可能会因为前面的某些放法是以m-1个连续的核物质结尾,加上这个导致这个解无效。我们要考虑的就是要去掉这些解。这些解一共多少呢?因为它们仅以m-1个连续的核物质结尾,换句话说,它们必然是以011..1(m-1个1)结尾的。所以是f(n-m-1,m)种情况。两者相减就得到了f(n,m)的式子。
于是我们只要开一个数组来计算就可以了。
#include<iostream>
using namespace std;
int main()
{
long long matrix[51][4];
int n,m,i,j;
for(j=0;j<4;j++)
{
for(i=0;i<j+2;i++)
matrix[i][j] = 1<<i;
matrix[i][j] = 2*matrix[i-1][j] - 1;
for(i++;i<51;i++)
matrix[i][j] = 2*matrix[i-1][j] - matrix[i-j-3][j];
}
while(cin>>n>>m)
cout<<matrix[n][m-2]<<endl;
return 0;
}
using namespace std;
int main()
{
long long matrix[51][4];
int n,m,i,j;
for(j=0;j<4;j++)
{
for(i=0;i<j+2;i++)
matrix[i][j] = 1<<i;
matrix[i][j] = 2*matrix[i-1][j] - 1;
for(i++;i<51;i++)
matrix[i][j] = 2*matrix[i-1][j] - matrix[i-j-3][j];
}
while(cin>>n>>m)
cout<<matrix[n][m-2]<<endl;
return 0;
}