• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
jacklee404
Never Stop!
博客园    首页    新随笔    联系   管理    订阅  订阅
AcWing 900. 整数划分-完全背包类计数DP

题目

一个正整数 nn 可以表示成若干个正整数之和,形如:n=n1+n2+…+nkn=n1+n2+…+nk,其中 n1≥n2≥…≥nk,k≥1n1≥n2≥…≥nk,k≥1。

我们将这样的一种表示称为正整数 nn 的一种划分。

现在给定一个正整数 nn,请你求出 nn 共有多少种不同的划分方法。

输入格式

共一行,包含一个整数 nn。

输出格式

共一行,包含一个整数,表示总划分数量。

由于答案可能很大,输出结果请对 1e9+7 取模。

数据范围

1≤n≤10001≤n≤1000

输入样例:

5

输出样例:

7

思路 (完全背包计数)

​ 和完全背包类似,\(dp[i][j]\)可以由\(dp[i - 1][j]\)和\(dp[i][j - v[i]] + w[i]\)递推而来,这里的\(v[i] = 1\),由于\(dp[i][j]\)表示考虑前\(i\)个物品,当背包容量为\(j\)时的方案数

因此dp方程可以写为

\(dp[i][j] = dp[i - 1][j] + dp[i][j - 1]\)

初始化:

\(dp[0][i] = 1\)

Code

#include <iostream>

using namespace std;
const int mod = 1e9 + 7;

int dp[1000];
// 完全背包计数问题
// dp[i][j] 表示考虑前i个物品, 当背包容量为j时的方案数
// dp[i][0] =  1;
// dp[i][1] =  1;
// dp[i][j] = dp[i - 1][j] + dp[i][j - i];
// dp[1][2] = 1
// dp[2][2] = 2 = dp[1][2] + dp[1][1]
// dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i])
// dp[j] = dp[j] + dp[j - v[i]]

int main() {
    dp[0] = 1;
    for(int i = 1; i <= 1000; i ++) {
        for(int j = i; j <= 1000; j ++) {
            dp[j] = (dp[j] % mod + dp[j - i] % mod) % mod;
        }
    }
    int n;
    cin >> n;
    cout << dp[n];
}
posted on 2023-01-14 10:53  Jack404  阅读(39)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3