それは完全なナップサック問題に変換することができます
。合計が正確にnになるように1からnまでのいくつかの数を選択します。合計でいくつの解がありますか?
dp [i] [j]は、前のi個の数から選択された解の数を表し、それらの合計が正確にjになるようにします。
i番目の数が何回選択されるかを考えてください
。dp[i][j]= dp [i-1] [j] + dp [i-1] [ji] + dp [i-1] [j-2 * i]+..。
時間の最適化:
dp [i] [ji] = dp [i-1] [ji] + dp [i-1] [j-2 * i] + dp [i-1] [j-3 * i] + ....
したがって、dp [i] [j] = dp [i-1] [j] + dp [i] [ji]
スペースの最適化:i 1〜nの
ローリングアレイ :ji〜nの場合:dp [j] = dp [j] + dp [ji]
コード:
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];