8288分类目录 8288分类目录 8288分类目录
  当前位置:海洋目录网 » 站长资讯 » 站长资讯 » 文章详细 订阅RssFeed

洛谷 模拟城市2.0

来源:本站原创 浏览:128次 时间:2021-10-13

一次洛谷月赛的T1,当时因为是信心赛,认为第一题应该不会太难,结果想了很久,直接额放弃正解选择暴力。。。简直就是巨坑的五维DP。。。mmd

题目背景

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

2048年,经过不懈努力,博弈终于被组织委以重任,成为D市市委书记!

他勤学好问,励精图治,很快把D市建设成富强民主文明和谐的美好城市。为了进一步深化发展,他决定在海边建立一个经济开发区。

题目描述

已知开发区的建筑地块是一个n×n的矩形,而开发区可以建造三种建筑: 商业楼,住宅楼,教学楼。这任何两座建筑可以堆叠,可以紧密相邻。他需要建造正好a座商业楼,b座住宅楼,c座教学楼。但是,城市建成后要应付检查,如果安排的太混乱会被批评。不过幸运的是,只有一条公路经过了该开发区的一侧,就是说,检察人员全程只能看到开发区的一面。

因此,他需要使得开发区建成后,从正面看去,只有一种类型的建筑。

一共有多少种满足条件的方案呢? 请输出方案数,并对10^9+7取模。

注意,对于同一个n,会有多组数据。

输入输出格式

输入格式:

第一行两个整数n,T

接下来T行,每行三个整数,表示该组数据的a,b,c

输出格式:

输出共T行,每行一个整数:表示各数据答案取模10^9+7的结果。

输入输出样例

输入样例#1: 

2 11 1 0

输出样例#1: 

4

输入样例#2: 

2 12 1 0

输出样例#2: 

8
说明

对于20%的数据,n≤2  a,b,c≤3  T≤5

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

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

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

对于全部100%的数据,a,b,c,n≤25  T≤5×105

样例1

 

样例2

 Solution:

正解DP+组合数。(可能有多种方法,这里说其中的一种)我们发现,从正面看,横排放置的方块会互相影响(因为后面的可能比前面高,状态太复杂且不好转移),我们可以考虑纵向放置的方案数。纵列和纵列之间不会相互遮挡,因此方案数很好统计。

所以我们需要处理出纵列合法的方案数。虽然有三种方块,但我们只是需要一种漏在外面,所以可以把另外两种先不考虑,把它们合成一个状态。
处理任意一列合法方案数,可以dfs处理,也可以dp。设f[i][j][k][x][y]表示放置到第 i个格子,高度为 j,已经放置的最高高度为 k,已经用了 x个能看见的方块,y 个不能看见的方块的方案数。边界条件:最高可以放到max(a,b,c),我们发现如果高度超过了所有种类颜色的数量,那么我们不可能使得这种情况合法。需要注意的是, y的最大值应当是2*max(a,b,c),因为我们把另外两种方块整合在一起了。那么就可以按顺序暴力的放置了。每个格子可能有两种操作,在它上面放一个新的格子,或者把下一个格子放到下一行去。如果下个位置的高度超过了枚举的最高高度,那么前面就没有格子可以遮挡它,它必须放能看见的种类,并更新最高高度。否则说明下个位置的高度不够高,会被前面已经放置的格子遮挡,那么放什么种类就都可以啦。

状态转移方程:

放到下一行:
 f[i+1][0][k][x][y]+=f[i][k][k][x][y];
放到上面:
 if (j==k)
     f[i][j+1][k+1][x+1][y]+=f[i][j][k][x][y];
else
     f[i][j+1][k][x+1][y]+=f[i][j][k][x][y],
    f[i][j+1][k][x][y+1]+=f[i][j][k][x][y];
复杂度O(n5)

为了方便统计,标程的 i计算到了n+1这样我们就可以处理出,因为i=n的所有情况都统计在了f[n+1][0]中。

这样我们就可以处理出g[i][j]表示在某一列上,用了i 种能看见的方块,j 种遮挡住的方块的方案数。每一行的方案数处理出来了,我们就可以开始真正的dp了。

设dp[i][j][k]表示从左往右(正面)放到第i 列,用了j 种能看见的方块, k种遮挡的方块的方案数。dp[i+1][j+x][y+k]+=dp[i][j][k]*g[x][y];

复杂度O(n5)

处理出dp数组之后,实际上我们就得到了答案的一部分。如果只有两种方块可供放置,那么dp数组就是答案了就是我先前说的b=0的部分。

但是我们有三种方块。考虑让一种方块漏出来,那么另外两种方块的位置是可以随意组合的(因为并不会漏在外面)。所以还需要处理一下组合数。数据范围很小,可以直接预处理。如果只让一种(如住宅楼)能看见,那么方案数已经显而易见了。

dp[n][a][b+c]*C[c+b][b];

dp表示使得a 漏在外面,b,c遮住的方案数。C 数组是组合数,表示一共有b+c个位置,b、c随意组合的方案数。

那么最终答案就呼之欲出了。

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]); 

我们发现其实对于同一个n ,处理出来的dp数组是完全一致的,我们可以将a,b,c处理到范围的最大值25,就可以O(1)查询得到对于不同a,b,c的答案了。
时间复杂度O(2*n5+常数),完全是可以过的(除非评测鸡太差)。 

输入数据很大,为了尽量减少常数的影响,建议使用快速读入。不过经过测试, scanf 理论是可以通过的。此题没有刻意卡常,各位可以随意踩std。

代码:
 1 #include 2 #define mod 1000000007 3 #define N 27 4 using namespace std;���ѷ���,ͬ��ԧ�� 5 inline int read() 6 { 7     int x=0,f=1;char ch=getchar(); 8     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 9     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}10     return x*f;11 }12 int f[N][N][N][N][N<<1],g[N][N<<1],C[N<<1][N<<1],dp[N][N][N<<1];13 int ans,a,b,c,n,m,T;14 inline void add(int &x,int y){x+=y;if (x>=mod) x-=mod;}15 main()16 {17     n=read(),T=read();18     m=25;19     f[0][0][0][0][0]=1;20     for (int i=0;i<n;i++)21         for (int j=0;j<=m;j++)22             for (int k=j;k<=m;k++)23                 for (int x=k;x<=m;x++)24                     for (int y=0;y<=(m<<1);y++)25                         if (f[i][j][k][x][y])26                         {27                             add(f[i+1][0][k][x][y],f[i][j][k][x][y]);28                             if (j==k)29                                 add(f[i][j+1][k+1][x+1][y],f[i][j][k][x][y]);30                             else31                                 add(f[i][j+1][k][x+1][y],f[i][j][k][x][y]),32                                 add(f[i][j+1][k][x][y+1],f[i][j][k][x][y]);33                         }34     for (int k=0;k<=m;k++)35         for (int x=k;x<=m;x++)36             for (int y=0;y<=(m<<1);y++)37                 add(g[x][y],f[n][0][k][x][y]);38     C[0][0]=1;39     for(int i=1;i<=(m<<1);i++)40     {41         C[i][0]=1;42         for(int j=1;j<=i;j++)43         {44             C[i][j]=C[i-1][j-1]+C[i-1][j];45             if (C[i][j]>=mod) C[i][j]-=mod;46         }47     }48     dp[0][0][0]=1;49     for (int i=0;i<n;i++)50         for (int j=0;j<=m;j++)51             for (int k=0;k<=(m<<1);k++)52                 if (dp[i][j][k])53                     for(int x=0;j+x<=m;x++)54                         for(int y=0;y+k<=(m<<1);y++)55                             add(dp[i+1][j+x][y+k],(1ll*dp[i][j][k]*g[x][y])%mod);56     while(T--)57     {58         a=read(),b=read(),c=read();59         ans=0;60         add(ans,(1ll*dp[n][a][b+c]*C[b+c][b])%mod);61         add(ans,(1ll*dp[n][b][c+a]*C[c+a][c])%mod);62         add(ans,(1ll*dp[n][c][a+b]*C[a+b][a])%mod);63         printf("%d\n",ans);    64     }65 }

 

  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net