这题主要是运用如下结论:
设标记P(n, m)表示正整数n的所有不同划分中,最大加数不大于m的划分个数。
[ 1 m = 1;
P(n, m) = [ P(n, n) n < m;
[ 1 + P(n, n-1) n = m;
[ P(n, m-1) + P(n-m, m) n > m > 1.
另外注意:这题不能用暴力,会超时的。
记忆化搜索。。。
#include <iostream>
#include <memory.h>
using namespace std;
int dp[32769][4];
int find(int n,int m)
{
if(m==1)
return 1;
if(n<m)
{
if(dp[n][n])
return dp[n][n];
else
dp[n][n]=find(n,n);
return dp[n][n];
}
if(n==m)
{
if(dp[n][n-1]==0)
dp[n][n-1]=find(n,n-1);
return 1+dp[n][n-1];
}
if(n>m)
{
if(dp[n-m][m]==0)
dp[n-m][m]=find(n-m,m);
if(dp[n][m-1]==0)
dp[n][m-1]=find(n,m-1);
return dp[n-m][m]+dp[n][m-1];
}
}
int main()
{
int n;
memset(dp,0,sizeof(dp));
while(cin >>n)
{
cout <<find(n,3)<<endl;
}
return 0;
}
方法二:
分两种情况讨论:
1.n都由1或者都由3或者由1和3共同组成。
2.由123组成
#include <iostream>
using namespace std;
int count(int n)
{
int cn=n/3+1;
int limit=n/3;
for(int i=0;i<=limit;i++)
{
cn+=(n-i*3)/2;
}
return cn;
}
int main()
{
int n;
while(cin >>n)
{
cout <<count(n)<<endl;
}
return 0;
}