jzoj3424. [simulation] painters NOIP2013

Description

Hector is a burly painters, and very like thinking = =
Now, the temple has N pillars arranged in a straight line, from 1 to N label, required by the elders of these pillars will paint fresh coat of paint. Hector tub has K different paint color, the paint can just paint bucket i Ci pillars, and, C1 + C2 + C3 ... CK = N ( i.e., N painting pillars just run all the paint). Elders to spite Hector, requires not the same color of the adjacent columns.
Hector like to think not only did not immediately began to paint, but began pondering some strange questions, such as how many paint programs, a total of?
In order to begin to paint as soon as Hector, you tell him the answer as soon as possible.

Input

The first line of a positive integer T, represents a set of test data
for each set of test data:
Line 1: a positive integer K
Line 2: K positive integer, i is the number of columns of the paint bucket can be painted, Ci.

Output

For each set of input data, output line an integer representing the number of programs stucco mod 1000000007.

Sample Input

3
3
1 2 3
5
2 2 2 2 2
10
1 1 2 2 3 3 4 4 5 5

Sample Output

10
39480
85937576

Data Constraint

30% N≤10, T≤5
50% N≤15, T≤5
80% K≤15,Ci≤5,T≤500
100% K≤15,Ci≤6,T≤2000

answer

Digression
saying this question a few days I also saw in the exam.
At that time no idea, did not want to go.
Today saw, suddenly had an idea, find a question is quite simple.
Tune for a long time, over a sample, pay up, the results TLE50.
Why? Because when I put the game f * 30,000 100 open into an array.
Then every time memset about 2000, successfully exploded.

Consider DP (saying violence is not good to score points)
we follow in order to get each pigment.
Then a pigment is added, only we need to consider the relative position of the current pigment and the pigment has to get that done, which need not be considered in the dye columns.
Means that, if the current pigments are: ababbd
added 3 c pigments way is: cacbabcbd
then we set \ (f _ {[i] } \) represents the sequence before the current i pigments made out of solution.
But the one-dimensional enough. Because the subject of the request is not the same color adjacent.
So we pay more, a total of one-dimensional representation of the current j-th position to meet in front of the same color with the current color.
Transfer to a little magic.
In fact, each transfer is equivalent to k new color balls inserted into the original sequence.
Method inserted -
each insert is possible to insert between the same two balls, may also be inserted between two different balls.
Therefore, with p balls inserted between two identical balls, q has a ball inserted into the ball between two non-identical.
The answer are: \ (C_J C_ {^ P * J + SUM-Q. 1} ^ \)
, but may also have other ball above the ball with the latter two.
This is equivalent to the number of n identical balls placed in the m different program box.
Program Number is the \ (+ C_ {n-m}. 1-n-^ {} \) (using the principle of the interposer)
and the answer is \ (C_ {k-1} ^ {kpq} \)

Standard process

#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
using namespace std;

int maxn=32768,mo=1000000007;
int n,t;
int k[16];
long long f[100][100],mi[16],c[100][100],sum[32768],len[32768];

long long qsm(long long a,long long b)
{
    long long t=1;
    long long y=a;
    while (b>0)
    {
        if (b%2==1) t=(t*y)%mo;
        y=(y*y)%mo;
        b=b/2; 
    }
    return t;
}

int main()
{
    freopen("color.in","r",stdin);
    for (int i=0;i<=100;i++)
    {
        c[i][0]=1;
        for (int j=1;j<=i;j++)
        {
            c[i][j]=(c[i-1][j-1]+c[i-1][j])%mo;
        }
    }
    
    mi[0]=1;
    for (int i=1;i<=15;i++)
    {
        mi[i]=mi[i-1]*2;
    }
    scanf("%d",&t);
    while (t>0)
    {
        t--;
        scanf("%d",&n);
        for (int i=1;i<=n;i++)
        {
            scanf("%d",&k[i]);
        }
        memset(f,0,sizeof(f));
        memset(sum,0,sizeof(sum));
        memset(len,0,sizeof(len));
        f[0][0]=1;
            for (int i=1;i<=n;i++)
            {
                    if (i==1)
                    {
                        f[i][k[i]-1]=1;
                        sum[i]=k[i];
                        len[i]=1;   
                    }
                    else
                    {
                        for (int j=0;j<=sum[i-1];j++) 
                        {
                            if (f[i-1][j]>0)
                            { 
                                for (int p=0;p<=min(k[i],j);p++)
                                {
                                    for (int q=0;q<=k[i]-p;q++)
                                    {
                                        if (q+p>=1)
                                        {
                                            f[i][j-p+k[i]-p-q]+=(f[i-1][j]*c[j][p]*c[sum[i-1]-j+1][q]*c[k[i]-1][k[i]-p-q])%mo;
                                        }
                                    }
                                }
                            }
                        }
                        sum[i]=sum[i-1]+k[i];
                        len[i]=len[i-1]+1;
                    }
                
            }
        printf("%lld\n",(f[n][0])%mo);
    }
}

Guess you like

Origin www.cnblogs.com/RainbowCrown/p/11285013.html