1. 程式人生 > >poj2279 Mr. Young's Picture Permutations(線性DP)

poj2279 Mr. Young's Picture Permutations(線性DP)

題目

一個k行,每行n[i]個數字的容器。給出Σn[i]個數字,填入該容器,使得每一行遞減,每一列遞減。求方案數。(k<=5,Σn[i]<=30)

思考

一般人會去思考,給第(i,j)填x的方案數。這樣問題就很複雜了,因為當填(i,j)時,要考慮(i-1,j)和(i,j-1)兩個格子的數字,而DP又不便記錄。 我們換一種想法,先說說一種樸素做法。記目前每行已填了(a[1],a[2],a[3],a[4],a[5])個數。現在,從大到小要填入一個數x,我們可以給它填在(1,a[1]+1)(前提a[1]+1<=n[i]),或者填在(i,a[i]+1)(i>1)(前提a[i]+1<=n[i]且a[i]+1<=a[i-1])。這樣填能保證最終有一個合法答案。 進而,我們可以忽略現在填數是什麼,因為只要按大到小的順序填下去,總是合法的,而且還一定能產生一些貢獻。或者理解成我們現在填的數是第Σa[i]+1大的數。

題解

DP 在上述樸素做法下,我們將其轉為DP的形式,累計方案數。 設f[a][b][c][d][e]表示每行已填了(a[1],a[2],a[3],a[4],a[5])個數的方案數。由於f[30][30][30][30][30]會MLE,所以要動態開陣列。 初始化:f[0][0][0][0][0]=1 轉移方程:在上述樸素做法的條件上,可以有(a[1],a[2],a[3],a[4],a[5])轉移到(a[1]+1,a[2],a[3],a[4],a[5]),(a[1],a[2]+1,a[3],a[4],a[5])…(a[1],a[2],a[3],a[4],a[5]+1)。

程式碼

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int k,n[10],a[10];

int main()
{
    while(scanf("%d",&k),k!=0)
    {
        memset(n,0,sizeof(n));
        for(int i=1;i<=k;i++) scanf("%d",&n[i]);
        unsigned f[n[1]+1][n[2]+1][n[3]+1][n[4]+1][n[5]+1];
        memset(f,0,sizeof(f));f[0][0][0][0][0]=1;
        for(a[1]=0; a[1]<=n[1]; a[1]++)
            for(a[2]=0; a[2]<=n[2]; a[2]++)
                for(a[3]=0; a[3]<=n[3]; a[3]++)
                    for(a[4]=0; a[4]<=n[4]; a[4]++)
                        for(a[5]=0; a[5]<=n[5]; a[5]++)
                        {
                            int tmp=f[a[1]][a[2]][a[3]][a[4]][a[5]];
                            if(a[1]<n[1]) f[a[1]+1][a[2]][a[3]][a[4]][a[5]]+=tmp;
                            if(a[2]<n[2] && a[2]<a[1]) f[a[1]][a[2]+1][a[3]][a[4]][a[5]]+=tmp;
                            if(a[3]<n[3] && a[3]<a[2]) f[a[1]][a[2]][a[3]+1][a[4]][a[5]]+=tmp;
                            if(a[4]<n[4] && a[4]<a[3]) f[a[1]][a[2]][a[3]][a[4]+1][a[5]]+=tmp;
                            if(a[5]<n[5] && a[5]<a[4]) f[a[1]][a[2]][a[3]][a[4]][a[5]+1]+=tmp;
                        }
        printf("%u\n",f[n[1]][n[2]][n[3]][n[4]][n[5]]);
    }
    return 0;
}