解题思路:
f[a][b][c]表示用a个A,b个B,c个C的方案数,其转移方程为:
if(b==0)f[a][b][c]=1;
else if(c==0)f[a][b][c]=f[a-1][b][c]+f[a][b-1][c];
else f[a][b][c]=f[a-1][b][c]+f[a][b-1][c]+f[a][b][c-1];
其中1
≤
a
≤
n,0
≤
b
≤
a,0
≤
c
≤
b;
时间复杂度为O(
n3
)。
但结果会很大,要用高精度加法,且要压位,详见代码。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#define ll long long
using namespace std;
int getint()
{
int i=0,f=1;char c;
for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar());
if(c=='-')c=getchar(),f=-1;
for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
return i*f;
}
const int N=61,p=10000;
int n,f[N][N][N][30];
void Add(int f1[],int f2[])
{
int l1,l2;
for(l1=29;l1;l1--)if(f1[l1])break;
for(l2=29;l2;l2--)if(f2[l2])break;
if(l1<l2)l1=l2;
for(int i=1;i<=l1;i++)f1[i]+=f2[i];
for(int i=1;i<=l1;i++)
if(f1[i]>=p)f1[i+1]+=f1[i]/p,f1[i]%=p;
}
void W(int f1[])
{
int l1;
for(l1=29;l1;l1--)if(f1[l1])break;
cout<<f1[l1--];
for(int i=l1;i;i--)
{
if(f1[i]<10)putchar('0'),putchar('0'),putchar('0');
else if(f1[i]<100)putchar('0'),putchar('0');
else if(f1[i]<1000)putchar('0');
cout<<f1[i];
}
cout<<'\n'<<'\n';
}
void pre()
{
int a,b,c;
for(a=1;a<=60;a++)
for(b=0;b<=a;b++)
for(c=0;c<=b;c++)
{
if(b==0)f[a][b][c][1]=1;
else if(c==0)
{
Add(f[a][b][c],f[a-1][b][c]);
Add(f[a][b][c],f[a][b-1][c]);
}
else
{
Add(f[a][b][c],f[a-1][b][c]);
Add(f[a][b][c],f[a][b-1][c]);
Add(f[a][b][c],f[a][b][c-1]);
}
}
}
int main()
{
//freopen("lx.in","r",stdin);
pre();
while(scanf("%d",&n)!=EOF)
W(f[n][n][n]);
return 0;
}