Enter 1 number N (1 <= N <= 50000).
The number of output divisions Mod 10^9 + 7.
6
4
Problem solution: Let dp[j][i] be the scheme that takes the first j numbers and the sum is i. To reach dp[j][i], there are two options:
The first scheme does not add new elements, that is, from dp[j][x] to dp[j][i], in order to ensure non-repetition, each element is +1, that is, x = i - j;
The second scheme adds new elements, that is, from dp[j - 1][x] to dp[j][i], in order to ensure that dp[j - 1][x] and dp[j][x] do not repeat, We found that the elements of dp[j][x] are all larger by 1, so the new element of dp[j - 1][x] is 1, that is, x = i - j;
So the transition equation is: dp[j][i] = dp[j][i - j] + dp[j - 1][i - j]. The time and space complexity of this method is O(n^2), and the timeout exceeds the memory!
Divide n numbers into two parts [0, (sqrt(n) + 0.9)),[(sqrt(n) + 0.9), n];
For the first part use 01 back. Time is O(n * (sqrt(n) + 0.9));
For the second part, each element is taken at most (sqrt(n) + 0.9) times, we define the first one to take j elements, so we can use the transition equation: dp[j][i] = dp[j] [i - j] + dp[j - 1][i - j]; Note that because the new element is not 1 but (sqrt(n) + 0.9), it is necessary to change the transfer equation,
The final equation is: dp[j][i] = dp[j][i - j] + dp[j - 1][i - j - (sqrt(n) + 0.9) + 1]; the complexity is also O(n * (sqrt(n) + 0.9)); record a f1 array,
f1[i] = ∑(1<=x<=(sqrt(n) + 0.9))dp[x][i];
Finally ride it up!
AC code
#include <stdio.h> #include <iostream> #include <string> #include <queue> #include <map> #include <vector> #include <algorithm> #include <string.h> #include <cmath> typedef long long ll; using namespace std; const ll maxn = 55555, mod = 1e9 + 7; ll dp[244][maxn] = {0}, f[maxn] = {0}, f1[maxn] = {0}; int main(){ ll n; scanf("%lld", &n); ll m = int(double(sqrt(n) + 0.9)); f[0] = f1[0] = 1; for(ll i = 1; i < m; i++){ for(ll j = n; j - i >= 0; j--) f[j] = (f[j] + f[j - i]) % mod; } dp[1][m] = 1; for(ll i = m; i <= n; i++){ for(ll j = 1; j <= m; j++){ dp[j][i] = (dp[j][i - j] + dp[j][i]) % mod; if(i - m - j + 1 >= 0) dp[j][i] = (dp[j][i] + dp[j - 1][i - m - j + 1]) % mod; f1[i] = (f1[i] + dp[j][i]) % mod; } } ll ans = 0; for(ll i = 0; i <= n; i++) ans = (ans + f1 [i] * f [n - i])% mod; printf("%lld\n", ans); return 0; }