首页 > 代码库 > 暑假训练-藏妹子之处(递推)
暑假训练-藏妹子之处(递推)
【题目描述】:
今天CZY又找到了三个妹子,有着收藏爱好的他想要找三个地方将妹子们藏起来,将一片空地抽象成一个R行C列的表格,CZY要选出3个单元格。但要满足如下的两个条件:
- 任意两个单元格都不在同一行。
- 任意两个单元格都不在同一列。
选取格子存在一个花费,而这个花费是三个格子两两之间曼哈顿距离的和(如(x1,y1)和(x,y2)的曼哈顿距离为|x1-x2|+|y1-y2|)。狗狗想知道的是,花费在minT到maxT之间的方案数有多少。
答案模1000000007。所谓的两种不同方案是指:只要它选中的单元格有一个不同,就认为是不同的方案。
【输入描述】:
一行,4个整数,R、C、minT、maxT。
【输出描述】:
一个整数,表示不同的选择方案数量模1000000007后的结果。
【样例输入1】:
3 3 1 20000
【样例输出1】:
6
【样例输入2】:
3 3 4 7
【样例输出2】:
0
【样例输入3】:
4 6 9 12
【样例输出3】:
264
【样例输入4】:
7 5 13 18
【样例输出4】:
1212
【样例输入5】:
4000 4000 4000 14000
【样例输出5】:
859690013
【时间限制、数据范围及描述】:
时间:1s 空间:128M
对于 30%的数据: 3<=R,C<=70。
对于100%的数据: 3<=R,C<=4000, 1<=minT<=maxT<=20000。
很容易发现发现对于三个点(x1,y1)(x2,y2)(x3,y3),如果任意交换坐标费用不变,所以题意变为枚举3个横坐标和3个纵坐标,算合理的方案数
对于x1,x2,x3 , y1,y2,y3,若有x1<x2<x3 , y1<y2<y3,则方案的费用是2(x3-x1)+2(y3-y1)。
所以,不妨令x1<x2<x3 , y1<y2<y3,则由排列组合易得,最后方案数乘6即为答案。
而(x1,y1)和(x3,y3)构成一个矩形,对于一个确定的矩形边框,它的费用是一定的,即2(x3-x1)+2(y3-y1),也就是矩形的边长。它对答案的贡献也是一定的,即(x3-x1-1)*(y3-y1-1)。这个矩形在r*c的大矩形中出现的次数也是给定的,设矩形长为x,宽为y,则出现了(r-x+1)*(c-y+1)次。那么直接枚举矩形的边长,然后就可以算出答案。
时间复杂度为O(n^2)
答案数×6是因为x不变y交换,全排列P(3,2)
1 #include "bits/stdc++.h" 2 using namespace std; 3 typedef long long LL; 4 const int mod=1000000007; 5 LL ans; 6 LL r,c,mn,mx; 7 int main(){ 8 freopen ("excel.in","r",stdin); 9 freopen ("excel.out","w",stdout); 10 int i,j,d; 11 scanf("%lld%lld%lld%lld",&r,&c,&mn,&mx); 12 for (i=3;i<=r;i++){ 13 for (j=3;j<=c;j++){ 14 d=2*((i-1)+(j-1)); 15 if (d>=mn && d<=mx) 16 ans=(ans+(i-2)*(j-2)%mod*(r-i+1)%mod*(c-j+1)%mod*6%mod)%mod; 17 } 18 } 19 printf("%lld",ans); 20 return 0; 21 }
22
暑假训练-藏妹子之处(递推)