1. 程式人生 > >CH5202 自然數拆分Lunatic版【完全背包】

CH5202 自然數拆分Lunatic版【完全背包】

不同 col ++ code 所有 之間 兩個 結果 efi

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\n", dp[n]); 28 printf("%d\n", (dp[n] - 1 + mod) % mod); 29 return 0; 30 }

CH5202 自然數拆分Lunatic版【完全背包】