0827 OpenJ#7219 复杂的整数划分问题

摘要
-背包问题的变形 使用01背包 完全背包解决
原题目摘要

-
描述

将正整数n 表示成一系列正整数之和,n=n1+n2+…+nk, 其中n1>=n2>=…>=nk>=1 k>=1
正整数n 的这种表示称为正整数n 的划分。

输入
标准的输入包含若干组测试数据。每组测试数据是一行输入数据,包括两个整数N 和 K。
(0 < N <= 50, 0 < K <= N)
输出
对于每组测试数据,输出以下三行数据:
第一行: N划分成K个正整数之和的划分数目
第二行: N划分成若干个不同正整数之和的划分数目
第三行: N划分成若干个奇正整数之和的划分数目
样例输入
5 2
样例输出
2
3
3
提示
第一行: 4+1, 3+2,
第二行: 5,4+1,3+2
第三行: 5,1+1+3, 1+1+1+1+1+1


题目理解
- 将第一个看做 选k个的满足一定数量的背包,第二个看成,N个中选择满足数量的01背包,第三个与第一个类似
注意
-第二个说的是不同的所以所有的数只能出现一次 四三个要求的是奇数 遇到偶数要转一下  可惜我目前觉得这样好做一点__  不过应该有其他的办法
日期
-2017 0827
附加
-
代码
-
#include <algorithm>
#include <iostream>
#include <memory>
#include <cstdio>

using namespace std;

#define MAX 55

int dp1[MAX][MAX][MAX];//h,w,m,1-h/0-w
int dp2[MAX][MAX];
int dp3[MAX][MAX];
int ans1=0;
int _dp3(int n,int m){//不超过n k个m的划分
    if(n<1) return 0;
    if(m==0) return 1;

    if(n%2==0) n--;
    if(dp3[n][m]!=-1) return dp3[n][m];
    int ans = 0;
    if(m>=n)ans+=_dp3(n,m-n);
    ans+=_dp3(n-1,m);
    return dp3[n][m]=ans;
}

int _dp2(int n,int m){//n不超过m的 不同划分 01
    if(n==0) return 1;
    if(n>0&&m==0)return 0;
    if(dp2[n][m]!=-1) return dp2[n][m];
    int ans = 0;
    if(n>=m) ans+=_dp2(n-m,m-1);
    ans+=_dp2(n,m-1);
    return dp2[n][m]=ans;
}

int _dp1(int n,int m,int k){//不超过n k个m的划分
    if(n<1) return 0;
    if(m==0&&k==0) return 1;
    if(k==0||m==0) return 0;
if(dp1[n][m][k]!=-1) return dp1[n][m][k];
    int ans = 0;
    if(m>=n)ans+=_dp1(n,m-n,k-1);
    ans+=_dp1(n-1,m,k);

    return dp1[n][m][k]=ans;
}
int n,k;
void solve(){
    
    cout<<_dp1(n,n,k)<<endl;
    cout<<_dp2(n,n)<<endl;
    cout<<_dp3(n,n)<<endl;
}

int main(){
    memset(dp1,-1,sizeof(dp1));
    memset(dp2,-1,sizeof(dp2));
    memset(dp3,-1,sizeof(dp3));
    while(~scanf("%d%d",&n,&k))solve();

    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值