整数拆分问题 动态规划解法

来源:互联网 发布:金丝绒连衣裙新款淘宝 编辑:程序博客网 时间:2024/05/06 23:21

题目链接

我们想要整数 M 拆分成 N 个正数的方案数

我们定义  dp[i][j] 将整数 j 拆分为 i 个正数之和

那么我们分情况考虑,这 i 个正数中是否包含1

如果包含      我们可以先去掉这个1,方案数就是 dp[i-1][j-1]

如果不包含  也就是说所有 i 个正数都 ≥2  那么我们可以把每个数都减一  方案数为 dp[i][j-i]

初始条件是 dp[0][0] = 1 

j ≥ i 的时候才有方案


AC代码:

/** @Author: wchhlbt* @Last Modified time: 2017-11-05*/#include <bits/stdc++.h>#define inf 0x3f3f3f3f#define pb push_back#define AA first#define BB second#define ONES(x) __builtin_popcount(x)#define _  << "  " <<using namespace std;typedef pair<int, int> P;typedef long long ll ;int dx[4] = {0,0,1,-1};int dy[4] = {1,-1,0,0};const double eps =1e-8;const int mod = 1000000007;const double PI = acos(-1.0);inline int read(){ int num;    scanf("%d",&num);   return num;}const int maxn = 200007;int dp[30][30];int main(){    //dp[i][j] 恰好用i个盘子容纳j个苹果的方案数    //将整数j拆分为i个正数之和    //存在1 和 不存在1两种情况    int n = 20;    dp[0][0] = 1;    for(int i = 1; i<=n; i++){        for(int j = i; j<=n; j++){            dp[i][j] = dp[i-1][j-1] + dp[i][j-i];        }    }    int a,b;    while(~scanf("%d%d",&a,&b)){        int ans = 0;        for(int i = 1; i<=b; i++){            ans += dp[i][a];        }           cout << ans << endl;    }    return 0;}


原创粉丝点击