模擬城市2.0
題目背景
博弈正在機房頹一個叫做《模擬城市2.0》的遊戲。
2048年,經過不懈努力,博弈終於被組織委以重任,成為D市市委書記!他勤學好問,勵精圖治,很快把D市建設成富強民主文明和諧的美好城市。為了進一步深化發展,他決定在海邊建立一個經濟開發區。
題目描述
已知開發區的建築地塊是一個n×nn \times nn×n的矩形,而開發區可以建造三種建築: 商業樓,住宅樓,教學樓。這任何兩座建築可以堆疊,可以緊密相鄰。他需要建造正好aaa座商業樓,bbb座住宅樓,ccc座教學樓。但是,城市建成後要應付檢查,如果安排的太混亂會被批評。不過幸運的是,只有一條公路經過了該開發區的一側,就是說,檢察人員全程只能看到開發區的一面。
因此,他需要使得開發區建成後,從正面看去,只有一種類型的建築。
一共有多少種滿足條件的方案呢? 請輸出方案數,並對109+710^9+7109+7取模。
註意,對於同一個nnn,會有多組數據。
輸入輸出格式
輸入格式:第一行兩個整數n,Tn,Tn,T
接下來T行,每行三個整數,表示該組數據的a,b,ca,b,ca,b,c
輸出格式:輸出共T行,每行一個整數:表示各數據答案取模109+710^9+7109+7的結果。
輸入輸出樣例
輸入樣例#1: 復制2 1 1 1 0輸出樣例#1: 復制
4輸入樣例#2: 復制
2 1 2 1 0輸出樣例#2:
8
說明
對於20%的數據,n≤2 a,b,c≤3 T≤5n \leq 2 \ \ a,b,c \leq 3 \ \ T \leq 5n≤2 a,b,c≤3 T≤5
對於另外10%的數據,n≤3 a,b,c≤4 T≤5n \leq 3 \ \ a,b,c \leq 4 \ \ T \leq 5n≤3 a,b,c≤4 T≤5
對於另外20%的數據,b=0b=0b=0
對於另外10%的數據,T≤10T \leq 10T≤10
對於全部100%的數據,a,b,c,n≤25 T≤5×105a,b,c,n \leq 25 \ \ T \leq 5\times 10^5a,b,c,n≤25 T≤5×105
樣例1
樣例2
縱列和縱列之間不會相互遮擋,因此方案數很好統計。
所以我們需要處理出縱列合法的方案數。
雖然有三種方塊,但我們只是需要一種漏在外面,所以可以把另外兩種先不考慮
令f[i][j][k][x][y]為第i格,高度為j,最高為k,可見的方格為x,不可見為y的方案數
放到下一格:
1 f[i+1][0][k][x][y]+=f[i][k][k][x][y];
放到上面:
1 if (j==k) 2 f[i][j+1][k+1][x+1][y]+=f[i][j][k][x][y]; 3 else 4 f[i][j+1][k][x+1][y]+=f[i][j][k][x][y], 5 f[i][j+1][k][x][y+1]+=f[i][j][k][x][y];
現在我們處理出了一列的方案數
g[x][y]表示∑f[n][0][i][x][y]
那麽對於一列,我們求出了可見數x,不可見數y的方案數
接下來考慮行,因為列之間不影響
dp[i][j][k]表示第i列可見數j,不可見數k的方案數
dp[i+1][x+j][y+k]+=dp[i][j][k]*g[x][y]
如果只讓一種(如住宅樓)能看見,那麽方案數已經顯而易見了。
1 dp[n][a][b+c]*C[c+b][b];
那麽最終答案就呼之欲出了。
1 ans=(dp[n][a][b+c]*C[b+c][b])+(dp[n][b][c+a]*C[c+a][c])+(dp[n][c][a+b]*C[a+b][a]);
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 typedef long long lol; 7 lol f[27][27][27][27][54],dp[27][27][54],C[54][54],g[54][54],ans; 8 lol Mod=1000000007; 9 int n,T; 10 int main() 11 {int i,j,k,x,y,a,b,c; 12 cin>>n>>T; 13 f[0][0][0][0][0]=1; 14 for (i=0;i<n;i++) 15 { 16 for (j=0;j<=25;j++) 17 { 18 for (k=j;k<=25;k++) 19 { 20 for (x=k;x<=25;x++) 21 { 22 for (y=0;y<=50;y++) 23 if (f[i][j][k][x][y]) 24 {//cout<<f[i][j][k][x][y]<<endl; 25 lol s=f[i][j][k][x][y]; 26 f[i+1][0][k][x][y]+=s,f[i+1][0][k][x][y]%=Mod; 27 if (j==k) 28 f[i][j+1][k+1][x+1][y]+=s,f[i][j+1][k+1][x+1][y]%=Mod; 29 else 30 { 31 f[i][j+1][k][x+1][y]+=s,f[i][j+1][k][x+1][y]%=Mod; 32 f[i][j+1][k][x][y+1]+=s,f[i][j+1][k][x][y+1]%=Mod; 33 } 34 } 35 } 36 } 37 } 38 } 39 for (i=0;i<=25;i++) 40 for (x=i;x<=25;x++) 41 for (y=0;y<=50;y++) 42 g[x][y]+=f[n][0][i][x][y],g[x][y]%=Mod; 43 dp[0][0][0]=1; 44 for (i=0;i<n;i++) 45 { 46 for (j=0;j<=25;j++) 47 { 48 for (k=0;k<=50;k++) 49 if (dp[i][j][k]) 50 {//cout<<dp[i][j][k]<<endl; 51 for (x=0;j+x<=25;x++) 52 for (y=0;k+y<=50;y++) 53 { 54 dp[i+1][j+x][k+y]+=dp[i][j][k]*g[x][y]%Mod; 55 dp[i+1][j+x][k+y]%=Mod; 56 } 57 } 58 } 59 } 60 C[0][0]=1; 61 for(i=1;i<=50;i++) 62 { 63 C[i][0]=1; 64 for(j=1;j<=i;j++) 65 { 66 C[i][j]=C[i-1][j-1]+C[i-1][j]; 67 if (C[i][j]>=Mod) C[i][j]-=Mod; 68 } 69 } 70 while (T--) 71 { 72 scanf("%d%d%d",&a,&b,&c); 73 //cout<<dp[n][a][b+c]<<‘ ‘<<dp[n][b][a+c]<<‘ ‘<<dp[n][c][a+b]<<endl; 74 ans=((dp[n][a][b+c]*C[b+c][b]%Mod)+(dp[n][b][a+c]*C[a+c][a]%Mod)+(dp[n][c][a+b]*C[a+b][a]%Mod))%Mod; 75 printf("%lld\n",ans); 76 } 77 }
模擬城市2.0