/.../发现新博客无法传照片,且洛谷博客管理是真的..还是牛客好..
设f[i][j][k]为前k种颜色填了任意i行j列..最后的答案就是f[i][j][c]的和...emm/
这个怎么转移呢?我们还需要一个数组,设g[i][j][k]为k个数量填了任意i行j列的方案数.如此状态转移即可写出来了..
ac代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+9;
const ll N=35,M=255;
ll f[N][N][N],g[N][N][M];
int a[N];
ll C[N*N][N*N];
inline void init()
{
    for(int i=0;i<=N*N-1;i++)
    {
        C[i][0]=1;
        for(int j=1;j<=i;j++)
            C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
    }
}


int main()
{
    init();
    ll n,m,c,ans=0;
    cin>>n>>m>>c;
    for(int i=1;i<=c;i++)   scanf("%d",&a[i]);
    for(ll i=1;i<=n;i++)
    {
        for(ll j=1;j<=m;j++)
        {
            for(ll k=1;k<=c;k++)
            {
                g[i][j][a[k]]=C[i*j][a[k]];
                if(i*j<a[k]) continue;
                for(ll l=1;l<=i;l++)
                {
                    for(ll r=1;r<=j;r++)
                    {
                        if(l<i||r<j) g[i][j][a[k]]=(g[i][j][a[k]]-g[l][r][a[k]]*C[i][l]%mod*C[j][r]%mod+mod)%mod;
                    }
                }
            }
        }
    }//边界问题???我现在还是很迷???
    f[0][0][0]=1;
    for(ll i=1;i<=n;i++)
    {
        for(ll j=1;j<=m;j++)
        {
            for(ll k=1;k<=c;k++)
            {
                for(ll l=0;l<=i-1;l++)
                {
                    for(ll r=0;r<=j-1;r++)
                    {
                        if((i-l)*(j-r)>=a[k]) f[i][j][k]=(f[i][j][k]+f[l][r][k-1]%mod*g[i-l][j-r][a[k]]%mod*C[n-l][i-l]%mod*C[m-r][j-r]%mod)%mod;
                    }
                }
            }
        }
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            ans=(ans+f[i][j][c])%mod;
            cout<<ans<<endl;
    if(ans==-1)    puts("你MBbug在哪???");
    return 0;
}