1.把問題看成整數劃分
f(n, m) 爲把n劃分爲最大值不超過m的劃分總數:
f(n, m) = 1; (m == 1) n個1
f(n, n); (m > n) 最大值m不可能大於n
f(n, m - 1) + 1; (m == n) 1個n 加上 最大值爲n-1的個數
f(n, m - 1) + f(n - m, m); f(n, m - 1) 的意思是最大值不包括m時的個數, f(n - m, m)的意思是劃分的數列中包含m,即剩下n-m個數的劃分個數。
此題可看成m == 3的劃分
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int N = 32800;
long long ans[N][4];
int dg(int n, int m)
{
if (ans[n][m])
return ans[n][m];
if (m == 1)
return ans[n][m] = 1;
if (m > n)
return ans[n][m] = dg(n, n);
if (m == n)
return ans[n][n] = dg(n, n - 1) + 1;
return ans[n][m] = dg(n, m - 1) + dg(n - m, m);
}
int main(void)
{
int n;
while (cin >> n)
{
cout << dg(n, 3)<< endl;
}
return 0;
2.看做完全揹包
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int N = 32800;
int dp[N];
int main(void)
{
int n;
dp[0] = 1;
for (int i = 1; i <= 3; ++i)
{
for (int j = 1; j < N; ++j)
{
dp[j] = dp[j] + dp[j - i];
}
}
while (cin >> n)
{
cout << dp[n] << endl;
}
return 0;
}