1. 程式人生 > >hihocoder 1124 : 好矩陣 dp

hihocoder 1124 : 好矩陣 dp

div pac ble height baseline align define -m 一個

好矩陣

時間限制:3000ms 單點時限:1000ms 內存限制:256MB

描寫敘述

給定n, m。一個n?×?m矩陣是好矩陣當且僅當它的每一個位置都是非負整數,且每行每列的和?≤?2。求好矩陣的個數。模109?+?7

輸入

第一行一個整數T,表示測試點個數。

以下T個測試點。

每一個測試點一行。包括兩個整數n。m。

1?≤?T?≤?104. 1?≤?n,?m?≤?100.

輸出

T行。

每行是相應測試點的答案。

例子輸入
1
2 2
例子輸出
26

題意非常easy。因為,數量非常大。假設考慮一個一個方格的放,要考慮橫向的,又要考慮豎向的,非常復雜,所以不可取。所以一排一排的放,假設,m是一定的,那麽。每一排僅僅須要考慮不超過2,且與前面已經排好的不沖突就能夠了。

dp[i][a][b]表示,第i排,有a列0,b列1,m - a - b列2,的個數則

dp[i+1][a][b]+= dp[i][a][b];//第i+1排全放0
dp[i+1][a-1][b] += (ll)a * dp[i][a][b];//第i+1排在和為0那些列放一個2
dp[i+1][a-1][b+1] += (ll)a * dp[i][a][b];//第i+1排和為1放一個1
dp[i+1][a-1][b]+= (ll)a * (ll) b * dp[i][a][b];//第i+1排和為0 和為1的列各選一個 放兩個1
dp[i+1][a][b-1] += (ll)b * dp[i][a][b];//第i+1排選一個和為1的列放一個1

dp[i+1][a-2][b+2] += (ll)(a * (a-1)/2) * dp[i][a][b];//第i+1排選兩個和為0放兩個1
dp[i+1][a][b-2] += (ll)(b * (b-1)/2) * dp[i][a][b];//第i+1排選兩個和為1的放兩個1

總復雜度為o(n^4);

#define N 105
#define M 100005
#define maxn 205
#define MOD 1000000007
int n,m,T;
ll dp[N][N][N],ans[N][N];
int main()
{
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    for(int m = 1;m<=100;m++){
        int n = 100;
        for(int i =0;i<=n;i++){
            for(int a = 0;a<=m;a++){
                for(int b = 0;b<=m;b++){
                    dp[i][a][b] = 0;
                }
            }
        }
        dp[0][m][0] = 1;
        for(int i = 0;i<n;i++){
            for(int a = 0;a<=m;a++){
                for(int b = 0;a + b<=m;b++){
                    dp[i+1][a][b]+= dp[i][a][b];
                    dp[i+1][a][b] %= MOD;
                    if(a >= 1){
                        dp[i+1][a-1][b] += (ll)a * dp[i][a][b];
                        dp[i+1][a-1][b] %= MOD;
                        dp[i+1][a-1][b+1] += (ll)a * dp[i][a][b];
                        dp[i+1][a-1][b+1] %= MOD;
                    }
                    if(a >= 1 && b >= 1){
                        dp[i+1][a-1][b]+= (ll)a * (ll) b * dp[i][a][b];
                        dp[i+1][a-1][b] %= MOD;
                    }
                    if(b >= 1 ){
                        dp[i+1][a][b-1] += (ll)b * dp[i][a][b];
                        dp[i+1][a][b-1] %= MOD;
                    }
                    if(a >= 2 ){
                        dp[i+1][a-2][b+2] += (ll)(a * (a-1)/2) * dp[i][a][b];
                        dp[i+1][a-2][b+2] %= MOD;
                    }
                    if(b >= 2 ){
                        dp[i+1][a][b-2] += (ll)(b * (b-1)/2) * dp[i][a][b];
                        dp[i+1][a][b-2] %= MOD;
                    }
                }
            }
            ans[i+1][m] = 0;
            for(int a = 0;a<=m;a++){
                for(int b = 0;b<=m;b++){
                    ans[i+1][m] += dp[i+1][a][b];
                    ans[i+1][m] %= MOD;
                }
            }
        }
    }
    while(S(T)!=EOF)
    {
        while(T--){
            int s,e;
            S2(s,e);
            printf("%lld\n",ans[s][e]);
        }
    }
    return 0;
}

hihocoder 1124 : 好矩陣 dp