整数拆分问题(从O(n^2优化到O(n*sqrt(n))

博客探讨了如何优化整数拆分问题,从最初的O(n^2)算法改进到O(n*sqrt(n))。内容包括不同类型的整数划分,如划分成不超过特定数的和、划分成特定数量的数、划分成奇数,以及优化算法的转移方程。最后提到了使用5边形数和一个公式解决相同数的整数划分问题。
摘要由CSDN通过智能技术生成

 1. 将n划分成若干正整数之和的划分数。
  2. 将n划分成k个正整数之和的划分数。
  3. 将n划分成最大数不超过k的划分数。
  4. 将n划分成若干奇正整数之和的划分数。
  5. 将n划分成若干不同整数之和的划分数。

1.将n划分成不大于m的划分法:
  1).若是划分多个整数可以存在相同的:
   dp[n][m]= dp[n][m-1]+ dp[n-m][m] dp[n][m]表示整数 n 的划分中,每个数不大于 m 的划分数。
  则划分数可以分为两种情况:
  a.划分中每个数都小于 m,相当于每个数不大于 m- 1, 故划分数为 dp[n][m-1].
   b.划分中有一个数为 m. 那就在 n中减去 m ,剩下的就相当于把 n-m 进行划分, 故划分数为 dp[n-m][m];
  2).若是划分多个不同的整数:
  dp[n][m]= dp[n][m-1]+ dp[n-m][m-1] dp[n][m]表示整数 n 的划分中,每个数不大于 m 的划分数。
   同样划分情况分为两种情况:
  a.划分中每个数都小于m,相当于每个数不大于 m-1,划分数为 dp[n][m-1].
  b.划分中有一个数为 m.在n中减去m,剩下相当对n-m进行划分,
   并且每一个数不大于m-1,故划分数为 dp[n-m][m-1]
  2.将n划分成k个数的划分法:
    dp[n][k]= dp[n-k][k]+ dp[n-1][k-1];
  方法可以分为两类:
    第一类: n 份中不包含 1 的分法,为保证每份都 >= 2,可以先拿出 k 个 1 分
  到每一份,然后再把剩下的 n- k 分成 k 份即可,分法有: dp[n-k][k]
     第二类: n 份中至少有一份为 1 的分法,可以先那出一个 1 作为单独的1份,剩
  下的 n- 1 再分成 k- 1 份即可,分法有:dp[n-1][k-1]
  
  3.将n划分成若干奇数的划分法:(不懂)
    g[i][j]:将i划分为j个偶数
    f[i][j]:将i划分为j个奇数
   g[i][j] = f[i - j][j];
  f[i][j] = f[i - 1][j - 1] + g[i - j][j];

以下给出O(n^2)算法

/*对于输入的 n,k; 
第一行: 将n划分成若干正整数之和的划分数。 
第二行: 将n划分成k个正整数之和的划分数。 
第三行: 将n划分成最大数不超过k的划分数。 
第四行: 将n划分成若干个 奇正整数之和的划分数。 
第五行: 将n划分成若干不同整数之和的划分数。 
第六行: 打印一个空行*/  
#include<iostream>  
#include <cstring>  
#include<vector>  
#include <cstdio>  
using namespace std;  
#define N 55+1  
int dp[N][N];  

int main()  
{  
    //分为若干个正整数和  
    //memset(dp,0,sizeof(dp));  
    int n,k;  
    int out[6];  
    while(cin>>n>>k)  
    {  
        memset(dp,0,sizeof(dp));  
        //任意个正整数和,则dp[i][j]表示i分解成最大不超过j的个数,  
        //分为最大是j和最大不是j,则dp[i][j]=dp[i-j][j]+dp[i][j-1];  
        dp[0][0]=1;  
        for (int i=0;i<=n;i++)  
        {  
          
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值