CH5202 自然数拆分Lunatic版完全背包

Posted wyboooo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CH5202 自然数拆分Lunatic版完全背包相关的知识,希望对你有一定的参考价值。

5202 自然数拆分Lunatic版 0x50「动态规划」例题

描述

给定一个自然数N,要求把N拆分成若干个正整数相加的形式,参与加法运算的数可以重复。求拆分的方案数 mod 2147483648的结果。1≤N≤4000。

输入格式

一个整数n。

输出格式

输出一个数,即所有方案数
因为这个数可能非常大,所以你只要输出这个数 mod 2147483648 的余数即可。

样例输入

7

样例输出

14

样例解释

输入7,则7拆分的结果是
7=1+6
7=1+1+5
7=1+1+1+4
7=1+1+1+1+3
7=1+1+1+1+1+2
7=1+1+1+1+1+1+1
7=1+1+1+2+2
7=1+1+2+3
7=1+2+4
7=1+2+2+2
7=1+3+3
7=2+5
7=2+2+3
7=3+4

一共有14种情况,所以输出14 mod 2147483648,即14

 

思路:

一个典型的完全背包例题。

与01背包不同的是他才用正序循环,这样的话就可以表示每种物品使用无限次。对应着dp[i,j] = dp[i, j - vi]+wi这种两个都是 i 阶段的状态之间的转移

 1 #include <bits/stdc++.h>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<stdio.h>
 6 #include<cstring>
 7 #include<map>
 8 
 9 #define inf 0x3f3f3f3f
10 using namespace std;
11 typedef long long LL;
12 
13 int n;
14 const LL mod = 2147483648;
15 int dp[4005];
16 
17 int main()
18 {
19     scanf("%d", &n);
20     memset(dp, 0, sizeof(dp));
21     dp[0] = 1;
22     for(int i = 1; i <= n; i++){
23         for(int j = i; j <= n; j++){
24             dp[j] = (dp[j] + dp[j - i]) % mod;
25         }
26     }
27     //printf("%d
", dp[n]);
28     printf("%d
", (dp[n] - 1 + mod) % mod);
29     return 0;
30 }

 
















以上是关于CH5202 自然数拆分Lunatic版完全背包的主要内容,如果未能解决你的问题,请参考以下文章

动态规划完全背包问题《自然数的拆分》

动态规划完全背包问题《自然数的拆分》

题解AcWing279自然数拆分

279. 自然数拆分

Acwing-279-自然数拆分(背包)

CH5E07 划分大理石(背包dp+二进制拆分)