2018 蓝桥杯省赛 B 组模拟赛(五)J. 程序设计:划分整数


       题目链接: https://nanti.jisuanke.com/t/25093

       这是一道关于整数划分问题的题,这种问题有很多种问法,很灵活,但是如果细心的去思考一下,不同的问法其实都是有关联的,想了解整数划分的大致所有问法的请看这篇博客:整数划分总结

       这道题就是一个将n分解成不多于k个数的问题,首先我们定义个dp[][]数组,则dp[i][j]表示将整数i分成不多于j个数的方案数。对于这个问题我们可以分解为两种情况

1、最大数等于j

2、最大数小于j

        对于第二种情况,他的划分方案为dp[i][j-1],表示将i划分成最大数不大于j-1的方案数,也就是i划分成最大数小于j的话分数了。对于第一种情况,最大数要等于j,满足的划分条件是dp[i-j][j],表示将i-j划分成不超过j的方案数,再将'+j'放到每个划分的后面也就得到了最大数等于j的方案数。

        这道题还有一点就是需要开long long。


AC代码:

#include 
#include 
#include 
#define ll long long
using namespace std;
int main()
{
  int a,b;
  scanf("%d%d",&a,&b);
  ll dp[305][305];
  memset(dp,0,sizeof(dp));
  dp[0][0] = 1;
  if(a == 1 || b == 1){
    printf("1\n");
    return 0;
  }
  for(int i=0;i<=a;i++){
    for(int j=1;j<=a;j++){
      if(i >= j){
        dp[i][j] = dp[i-j][j] + dp[i][j-1];
      }
      else if(j > i){
        dp[i][j] = dp[i][i];
      }
    }
  }
  printf("%lld\n",dp[a][b]);

  return 0;
}



你可能感兴趣的:(2018 蓝桥杯省赛 B 组模拟赛(五)J. 程序设计:划分整数)