http://acm.timus.ru/problem.aspx?space=1&num=1276
用 ans[numaa][numab][numba][numbb][0] 表示用 numaa个AA numab个AB numba个BA numbb个BB 以 A为结尾的种类数量
用 ans[numaa][numab][numba][numbb][1] 表示用 numaa个AA numab个AB numba个BA numbb个BB 以 B为结尾的种类数量
然后根据结尾是A还是B 进行向后更新数量
代码:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<string>
#include<queue>
#include<stack>
#include <iomanip>
using namespace std;
#define LL long long
const int INF=0x3f3f3f3f;
const int N=45;
LL ans[20005][2];
int aa,ab,ba,bb;
int F(int i,int j,int l,int r)
{
int x=r;
x+=(l*bb);
x+=(j*ba*bb);
x+=(i*ab*ba*bb);
return x;
}
int main()
{
//freopen("data.in","r",stdin);
int n,k;
while(cin>>n>>k)
{
ab=0;aa=0;ba=0;bb=0;
string stmp;
int locomotive;
cin>>stmp;
if(stmp=="AA") locomotive=0;
if(stmp=="AB") locomotive=1;
if(stmp=="BA") locomotive=2;
if(stmp=="BB") locomotive=3;
for(int i=1;i<=n;++i)
{
cin>>stmp;
if(stmp=="AA") ++aa;
if(stmp=="AB") ++ab;
if(stmp=="BA") ++ba;
if(stmp=="BB") ++bb;
}
++aa;++ab;++ba;++bb;
memset(ans,0,sizeof(ans));
if(locomotive==0||locomotive==2)
ans[0][0]=1;
else
ans[0][1]=1;
LL sum=0;
for(int i=0;i<aa;++i)
for(int j=0;j<ab;++j)
for(int l=0;l<ba;++l)
for(int r=0;r<bb;++r)
if(i+j+l+r<=k)
{
int x=F(i,j,l,r);
if(i+j+l+r==k)
{
if(locomotive==0||locomotive==1)
sum+=ans[x][0];
else
sum+=ans[x][1];
}
if(ans[x][0]!=0)
{
if(i+1<aa)
ans[F(i+1,j,l,r)][0]+=ans[x][0];
if(j+1<ab)
ans[F(i,j+1,l,r)][1]+=ans[x][0];
}
if(ans[x][1]!=0)
{
if(l+1<ba)
ans[F(i,j,l+1,r)][0]+=ans[x][1];
if(r+1<bb)
ans[F(i,j,l,r+1)][1]+=ans[x][1];
}
}
if(sum==0)
cout<<"NO"<<endl;
else
{cout<<"YES"<<endl;cout<<sum<<endl;}
}
return 0;
}