It can be transformed into a complete knapsack problem
. Select several numbers from 1 to n so that their sum is exactly n. How many solutions are there in total?
dp[i][j] represents the number of solutions selected from the previous i numbers so that their sum is exactly j
Consider how many times the i-th number is selected
dp[i][j]=dp[i-1][j]+dp[i-1][ji]+dp[i-1][j-2*i]+ ...
Time optimization:
note that dp[i][ji]=dp[i-1][ji]+dp[i-1][j-2*i]+dp[i-1][j-3*i] +....
so dp[i][j]=dp[i-1][j]+dp[i][ji]
Space optimization:
rolling array
for i 1~n:
for ji~n: dp[j]=dp[j]+dp[ji]
Code:
int n;
cin>>n;
memset(dp,0,sizeof(dp));
dp[0]=1;
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
dp[j]=(dp[j]+dp[j-i])%mod;
}
}
cout<<dp[n];