#incl"> 模拟城市2.0 - 11GX
首页 > 模拟城市2.0

模拟城市2.0

题目背景

博弈正在机房颓一个叫做《模拟城市2.0》的游戏。

2048年,经过不懈努力,博弈终于被组织委以重任,成为D市市委书记!他勤学好问,励精图治,很快把D市建设成富强民主文明和谐的美好城市。为了进一步深化发展,他决定在海边建立一个经济开发区。

题目描述

已知开发区的建筑地块是一个n×nn imes 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 5n2  a,b,c3  T5

对于另外10%的数据,n≤3  a,b,c≤4  T≤5n leq 3 a,b,c leq 4 T leq 5n3  a,b,c4  T5

对于另外20%的数据,b=0b=0b=0

对于另外10%的数据,T≤10T leq 10T10

对于全部100%的数据,a,b,c,n≤25  T≤5×105a,b,c,n leq 25 T leq 5 imes 10^5a,b,c,n25  T5×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
 2 #include
 3 #include
 4 #include
 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)
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<
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)
45     {
46       for (j=0;j<=25;j++)
47     {
48       for (k=0;k<=50;k++)
49         if (dp[i][j][k])
50           { //cout<
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<
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
",ans);
76     }
77 }

 

转载于:https://www.cnblogs.com/Y-E-T-I/p/7788956.html

更多相关:

  • 题目:正则表达式匹配 请实现一个函数用来匹配包含'. '和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但与"aa.a"和"ab*a"均不匹配。 示例 1:...

  • 题意:就是在n*m的格子中放“炮”(中国象棋中的棋子)问有多少种放法,使得没有任意的两个炮相互攻击 思路:我们很容易的得到一列或者一行中最多放下两个炮(我也只能得到这些了,满脑子状压,但数据范围有100),这篇博客些的很好(传送门),我们定义dp[i][j][k]代表前i行我们有j列式有2个棋子,有k列是一个棋子,那么我们空的列的个数...

  • 虽然也是一道dp的入门题,但就是想不到,或者说不会实现。dp还是要多做题。 链接:https://www.luogu.org/problemnew/show/P1164   我们可以设dp[i][j]表示以考虑完第i件,恰好消费j元的方案数。那么dp[i][j]=dp[i-1][j]+dp[i-1][j-a[i]],也就是讨论第i件点...

  • bzoj1260,懒得复制,戳我戳我 Solution: 这种题目我不会做qwq,太菜了区间打牌(dp) 用f[l][r]表示从l到r最少需要染几次色。状态转移方程: 1.(f[l][r]=min(f[l][i],f[i+1][r]) (l<=i

  • 用python编写乘法口诀表的方法 发布时间:2020-08-25 11:46:35 来源:亿速云 阅读:60 作者:小新 用python编写乘法口诀表的方法?这个问题可能是我们日常学习或工作经常见到的。希望通过这个问题能让你收获颇深。下面是小编给大家带来的参考内容,让我们一起来看看吧! 第一种:使用for遍历循环嵌套for x in...

  • //很长一段时间我都只使用以下方式做数组循环,具体原因看数据 var aa = for (var i = 0, l = aa.length; i < l; i++) { var a = aa[i];} 数据采集图片来源于网友 很明显,for循环第二种方式完胜!!! 至于for in、forEach什么的,不知道甩他们多少...

  • 目录 1. Scene Graph Generation with External Knowledge and Image Reconstruction 2. Knowledge Acquisition for Visual Question Answering via Iterative Querying Author...

  • 基础题1: 输入一个正整数 n (1≤n≤10)和n 阶方阵a的元素,如果方阵a中的所有元素都沿主对角线对称,输出“Yes”, 否则,输出“No”。主对角线为从矩阵的左上角至右下角的连线,方阵a中的所有元素都沿主对角线对称指对所有i, k,a[i][k]和a[k][i]相等。输入输出示例如下: 输入: 3 1 2 3 4 5 6 7...

  • 程序流程控制 分支 顺序 循环 if switch&case 1 2 3 调整 break 1.6 前 switch(byte、short、char、int) 1.7 可放String 循环 while(次数不确定) do while for(确定次数) break(跳出本层循环) continue(跳出本次循环)     *   2...

  • 需要用到概率论的容斥定理以及计算1 ^ 4 + 2 ^ 4 + ……+ n ^ 4的计算公式1^4+2^4+……+n^4=n(n+1)(2n+1)(3n^2+3n-1)/30   #pragma comment(linker,"/STACK:1024000000,1024000000") #include #incl...