自然数拆分Lunatic版
题目描述
输入自然数 n n n ,然后将其拆分成由若干数相加的形式,参与加法运算的数可以重复。
输入格式
输入只有一个整数 n n n ,表示待拆分的自然数 n n n 。 0 < n < = 4000 0<n<=4000 0<n<=4000
P S : 0 PS:0 PS:0也算自然数,所以这里应该写正整数比较好
但是为了尊重原作者的版权(这有版权吗- -),没有改掉。
输出格式
输出一个数,即所有方案数
因为这个数可能非常大,所以你只要输出这个数 m o d / ; 2147483648 mod /;2147483648 mod/;2147483648 的余数即可。
Sample Input
7
Sample Output
14
Hint
解释:
输入 7 7 7 ,则 7 7 7 拆分的结果是
7 = 1 + 6 7=1+6 7=1+6
7 = 1 + 1 + 5 7=1+1+5 7=1+1+5
7 = 1 + 1 + 1 + 4 7=1+1+1+4 7=1+1+1+4
7 = 1 + 1 + 1 + 1 + 3 7=1+1+1+1+3 7=1+1+1+1+3
7 = 1 + 1 + 1 + 1 + 1 + 2 7=1+1+1+1+1+2 7=1+1+1+1+1+2
7 = 1 + 1 + 1 + 1 + 1 + 1 + 1 7=1+1+1+1+1+1+1 7=1+1+1+1+1+1+1
7 = 1 + 1 + 1 + 2 + 2 7=1+1+1+2+2 7=1+1+1+2+2
7 = 1 + 1 + 2 + 3 7=1+1+2+3 7=1+1+2+3
7 = 1 + 2 + 4 7=1+2+4 7=1+2+4
7 = 1 + 2 + 2 + 2 7=1+2+2+2 7=1+2+2+2
7 = 1 + 3 + 3 7=1+3+3 7=1+3+3
7 = 2 + 5 7=2+5 7=2+5
7 = 2 + 2 + 3 7=2+2+3 7=2+2+3
7 = 3 + 4 7=3+4 7=3+4
一共有 14 14 14 种情况,所以输出 14 m o d 2147483648 14\;\; mod \;\;2147483648 14mod2147483648,即 14 14 14
Limitation
各个测试点1s
#include<bits/stdc++.h>
using namespace std;
#define N 50010
long long f[N],n;
int main()
{
scanf("%lld",&n);
f[0] = 1;
for(int i = 1 ; i <= n ; i ++)
for(int j = i ; j <= n ; j ++)
f[j] = (f[j] + f[j-i]) % 2147483648ll;
cout << f[n] - 1;
return 0;
}
裸 完全背包 的水题一个,但是由于模数比较大不在模数后面加
l
l
ll
ll 或者
u
u
u 的话,会提示
完全背包和
01
01
01背包区别在于同一个元素可以多次使用,所以是从小到大的
f
o
r
for
for循环
除此之外和【动态规划】之简单01背包《数字拆分》差不多一样的。
在 完全背包 中,一个物品可以多次使用,这就是为什么 f o r for for 循环要正向进行(这个我在01背包中当成反例来讲过了)。