luogu 3158 [CQOI2011] put the pieces

After a lapse of several days I've come to challenge this road dp.

A few months ago to write a self-closing. A few months later to.

First, we listed a state is f [i] transfer behavior of a front line ... but i find that at this time we can not control columns and pieces of color, we have to put the number in the state.

Dp This is not a complete or high complexity of the dp.

We have to change a state can expect due to the color of each chess piece independent so we do not need several pieces of color mixing seek solutions.

It may be one kind of put the pieces of one color.

Therefore, a state where f [i] [j] [k] denotes the front i pieces color scheme occupation number j rows and K columns.

Such state of rows and columns have we just need to arrange how to put the current color.

Current color a [i] pawn. Enumerate what so many pieces can occupy the line l r columns.

We found it difficult to form with a [i] pawn perfect occupation line l r columns. However, if a [i] <l || a [i] <r 0 is the number of programs clearly.

Set S = Number of vacant position C (S, a [i]) forced us to the arrangement position. Then subtract illegal scheme.

= Not occupy illegal program enough not occupy enough l + r row lines - both before the intersection.

Here inclusion and exclusion of which is similar to the one thing on behalf of dollars of inclusion and exclusion. L be described clearly not be the most <= l-1 are not the same is true for valid column.

The last two are not lawful to be added back to the intersection.

But this inclusion-exclusion is wrong reasons is that we do not have the legal status of the program may be repeated as l-1 line is not legitimate we have to take out a C (l, l-1) * l-1 line is not legitimate .

Careful observation is not lawful l-1 line does not mean l-1 line all occupied so outside and then multiplied by l illustrate some of the program is double counting but do not do not do not need to enumerate a legitimate program which row is not Take up.

Therefore, we consider a new inclusion-exclusion this time we do not precisely defined as legitimate programs accounted for wl, wr line to ensure that they have been accounted for so as not to appear above situation.

But wl, wr need to enumerate all we need to give illegal to lose. This is \ (c \ cdot n ^ 3 \ cdot m ^ 3 \) found that pretreatment thing about it will be apparent to a reduction in complexity nm.

Such overall complexity as \ (sum \ cdot n ^ 2 \ cdot m ^ 2 \) by. I finally defeated the question head.

Some fainted. .

Note that open longlong (I think that a place will not burst then burst Do not think!

For pre-treatment we just need to deal with a [i] I did not want to put 1 ~ mx gave a good deal.

const int MAXN=31,maxn=2010;
int n,m,c,maxx,mx;
int a[MAXN],vis[maxn];
ll g[maxn][MAXN][MAXN];//表示i个棋子占了j行k列的方案数。
ll f[MAXN][MAXN][MAXN];//f[i][j][k]表示前i种颜色占了i行j列的方案数.
ll fac[maxn],inv[maxn],ans;
inline int ksm(ll b,int p)
{
    ll cnt=1;
    while(p)
    {
        if(p&1)cnt=cnt*b%mod;
        b=b*b%mod;
        p=p>>1;
    }
    return cnt;
}
inline void prepare()
{
    fac[0]=1;
    rep(1,maxx,i)fac[i]=fac[i-1]*i%mod;
    inv[maxx]=ksm(fac[maxx],mod-2);
    for(int i=maxx-1;i>=0;--i)inv[i]=inv[i+1]*(i+1)%mod;
}
inline ll C(int a,int b)
{
    if(a<b)return 0;
    return fac[a]*inv[b]%mod*inv[a-b]%mod;
}
int main()
{
    //freopen("1.in","r",stdin);
    get(n);get(m);get(c);
    rep(1,c,i)get(a[i]),mx=max(mx,a[i]),vis[a[i]]=1;
    maxx=n*m;prepare();
    f[0][0][0]=1;g[0][0][0]=1;
    rep(1,mx,i)
    {
        if(!vis[i])continue;
        rep(1,n,j)rep(1,m,k)
        {
            if(i<j||i<k)continue;
            rep(1,j,w1)rep(1,k,w2)
            {
                if(w1==j&&k==w2)g[i][j][k]=(g[i][j][k]+C(j*k,i))%mod;
                else g[i][j][k]=(g[i][j][k]-C(j,w1)*C(k,w2)%mod*g[i][w1][w2]%mod)%mod;
            }
        }
    }
    rep(1,c,i)//前i种颜色
    {
        rep(0,n,j)rep(0,m,k)
        {
            if(!f[i-1][j][k])continue;
            rep(1,n-j,l)rep(1,m-k,r)
            {
                if(a[i]<l||a[i]<r)continue;
                f[i][j+l][k+r]=(f[i][j+l][k+r]+C(n-j,l)*C(m-k,r)%mod*f[i-1][j][k]%mod*g[a[i]][l][r]%mod)%mod;
            }
        }
    }
    rep(1,n,j)rep(1,m,k)ans=(ans+f[c][j][k])%mod;
    printf("%lld\n",(ans+mod)%mod);
    return 0;
}

Guess you like

Origin www.cnblogs.com/chdy/p/12513226.html