2月12日 递推 数的划分(后半部分)

这三道题乍一看可能差不多,实际上还是有一定区别在其中。

总而言之:

1、要我们把一个数i分成j个数,使这j个数加起来等于i。

2、第二题就是比第一题要多考虑个零。

3、第三题就是要保证前面的数小于后面的数(当然你喜欢也可以写成让前面的数一定大于后面的数)。

放代码:

1、

#include<bits/stdc++.h>
using namespace std;
int n,m;
long long f[55][55];
int main()
{
cin >> n >> m;
for(int i = 1;i <= n;i++)
{
f[i][i] = f[i][1] = 2;
}
for(int j = 0;j <= m;j++)
{
for(int i = 0;i <= n;i++)
{
if(!f[i][j])
{
for(int x = 1;x <= i;x++)
{
f[i][j] +=  f[i - x][j - 1];
}
}
}
}
cout << f[n][m];
return 0;

}

2、#include<bits/stdc++.h>
using namespace std;
int n,m;
long long f[55][55];
int main()
{
cin >> n >> m;
for(int j = 1;j <= m;j++)
{
for(int i = 0;i <= n;i++)
{
if(j == 1 || i == 0)
{
f[i][j] = 1;
continue;

if(i == 1)
{
f[i][j] = j;
continue;
}
f[i][j] = f[i - 1][j] + f[i][j - 1];
}
}
cout << f[n][m];
return 0;

扫描二维码关注公众号,回复: 1624473 查看本文章

}

3、

#include<bits/stdc++.h>
using namespace std;
int g[10][205];
int main()
 {   
    int n,k,i,j;
    cin >> n >> k;
for(j = 0;j <= n;j++)
        g[1][j] = 1;
for(i = 2;i <= k;i++)
    for(j = 0;j <= n-k;j++)
if(j >= i)
        g[i][j] = g[i-1][j]+g[i][j-i];
        else
        g[i][j] = g[i-1][j];
    cout << g[k][n-k] << endl;         
    return 0;

 }   

总而言之就是要画个表找规律,,,但是如果可以直接通过题意进行爆炸分析能力也可以。。

关于1、还有一种用组合的做法,但亲测实在是容易数据溢出。。。

附上:

#include<bits/stdc++.h>
using namespace std;
int main()
{
//这边用了组合数的公式来做: n!/(m!*(n - m)!)  从n中任取m个。 
int n,m;
cin >> n >> m;
long long x,y,z;//用浮点数方便用除法 
x = y = z = 1;
//三次预处理 
for(int i = 1;i < n;i++)
{
x *= i;
}
for(int j = 1;j < m;j++)
{
y *= j;
}
for(int k = 1;k <= n - m;k++)//实际上是等于((n - 1) - (m - 1))!
{
z *= k;
}
cout << x /(y * z);
return 0;
 } 

猜你喜欢

转载自blog.csdn.net/chang_yl/article/details/79319217
今日推荐