jzoj 3424 [シミュレーション]画家NOIP2013

説明

ヘクターはたくましい画家、そして非常に= =思考のようなものです

今、これらの柱の年長者によって要求される1からNのラベルに、直線状に配置されたN個のテンプル柱は、塗料の新鮮なコートを描くであろうがあります。ヘクター浴槽がK異なる塗色を有し、塗料はちょうどI CIピラーをバケツペイント、及びでき、C1 + C2 + C3 ... CK = N(即ち、N塗装柱がちょうどすべてのペイントを実行します)。にもかかわらずヘクターの長老は、隣接する列の同じ色をしませ​​必要です。

ヘクターはないだけで、すぐにペイントし始めたが、そのようなどのように多くのペイントプログラム、の合計としていくつかの奇妙な質問に、熟考し始めていなかったと考えたいですか?

すぐヘクターとしてペイントを開始するためには、できるだけ早く彼に答えを教えてください。

入力

正の整数Tの最初の行は、テストデータのセットを表します

テストデータの各セットの場合:

1行目:正の整数K

2行目:Kの正の整数、私はペンキのバケツの列数は、CIを塗装することができます。

出力

入力データの各セットは、出力ラインプログラムスタッコMOD十億七の数を表す整数ため。

サンプル入力

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

サンプル出力

10
39480
85937576

データ制約

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

溶液

当初、私はそれは、結論の問題だったことはDPとは思わなかったと思いました。
我々は、セット\が(F [I] [J] \)本実施例は、j列隣接色の同じ数を有し、i番目のカラーブラシを表します。
カラーブロックの数に注意ブラシは今\(S \)(\ (Cする[1] \) \(C [I] \)
最初のため\(I + 1 \)色、ブラシができる\(Cを[I + 1] \)回。
我々はk個のブロックにそれを置くと、ブロックが挿入されています。
ある特徴と\(Lの\)ブロックは中央の列に隣接する同色に挿入されています。
したがって、伝達方程式が得られる。
。。[F [I + 1] [J + C [I-KL + 1] + = F [I] [J] * C(J、L)* C(C [\しますI + 1] -1、K- 1)* C(N-J + 1、KL)\]

コード

#include <cstdio>
#include <cstring>
#define K 16
#define N 110
#define mo 1000000007
#define ll long long
#define mem(a, x) memset(a, x, sizeof a)
#define fo(x, a, b) for (int x = a; x <= b; x++)
#define fd(x, a, b) for (int x = a; x >= b; x--)
using namespace std;
int T, n, m, c[N];
ll f[N][N], jc[N], ny[N];

inline int read()
{
    int x = 0; char c = getchar();
    while (c < '0' || c > '9') c = getchar();
    while (c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    return x;
}

ll ksm(ll x, int y)
{
    ll s = 1;
    while (y)
    {
        if (y & 1) s = s * x % mo;
        x = x * x % mo; y >>= 1;
    }
    return s;
}

ll C(ll x, ll y) {return jc[x] * ny[y] % mo * ny[x - y] % mo;}

int main()
{
    freopen("paint.in", "r", stdin);
    freopen("paint.out", "w", stdout);
    jc[0] = 1; fo(i, 1, 90) jc[i] = jc[i - 1] * i % mo;
    ny[90] = ksm(jc[90], mo - 2);
    fd(i, 89, 0) ny[i] = ny[i + 1] * (i + 1) % mo;
    T = read();
    while (T--)
    {
        m = read(); n = 0;
        fo(i, 1, m) c[i] = read();
        mem(f, 0);
        f[1][c[1] - 1] = 1;
        fo(i, 1, m - 1)
        {
            n += c[i];
            fo(j, 0, n)
                fo(k, 1, c[i + 1])
                    fo(l, 0, (j < k ? j : k))
                        f[i + 1][j + c[i + 1] - k - l] += f[i][j] * C(j, l) % mo * C(c[i + 1] - 1, k - 1) % mo * C(n - j + 1, k - l) % mo;
        }
        printf("%lld\n", f[m][0] % mo);
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/jz929/p/11286421.html