ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2021牛客OI赛前集训营-方格计数【计数,dp】

2021-10-07 09:34:49  阅读:225  来源: 互联网

标签:include frac OI leq ll 计数 枚举 ans 集训营


正题

题目链接:https://ac.nowcoder.com/acm/contest/20107/B


题目大意

给出一个\(w\times h\)的网格图,然后要求在上面选出\(n\)个格点,使得它们在一条直线上且两两之间距离不小于\(d\)。

\(1\leq T\leq 20,1\leq w,h,d\leq 500,1\leq n\leq 50\)


解题思路

先只考虑横竖和斜向右下的直线
显然是枚举直线更加迅速,可以枚举一个斜率\(\frac{a}{b}\),然后为了防止算重我们考虑起点也就是我们选择的最第一个点,对于起点在\((0,0)\sim (w-ka,h-kb)\)的矩形内的点,右下角至少还有\(k\)个点可以选择,我们可以枚举这个\(k\),然后暴力统计。这样一次复杂度是\(O(min\{\frac{w}{a},\frac{h}{b}\})\),类似于调和级数不是很大。

之后考虑统计选择的方案,设\(f_{i,j,k}\)表示选择的两个之间要至少相隔\(i\),有\(j\)个可以选,选择\(k\)个的方案,这个可以直接\(dp\)。

就可以过了,时间复杂度:\(O(whn+Twh\log {wh})\)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
const ll N=510,P=1e9+7;
ll T,n,w,h,D,ans,d[N][N];
int f[N][N][N];
signed main()
{
	scanf("%lld",&T);
	for(ll i=1;i<=500;i++)d[i][0]=d[0][i]=i;
	for(ll i=1;i<=500;i++)
		for(ll j=1;j<=i;j++)d[i][j]=d[j][i]=d[j][i%j];
	for(ll i=1;i<=500;i++){
		f[i][0][0]=1;
		for(ll j=1;j<=500;j++){
			for(ll k=0;k<=500;k++)f[i][j][k]=f[i][j-1][k];
			if(j>=i)
				for(ll k=1;k<=500;k++)
					(f[i][j][k]+=f[i][j-i][k-1])%=P;
		}
	}
	while(T--){
		scanf("%lld%lld%lld%lld",&n,&w,&h,&D);
		if(n==1){printf("%lld\n",(w+1)*(h+1)%P);continue;}
		ans=0;
		for(ll i=0;i<=w;i++)
			for(ll j=0;j<=h;j++){
				if(d[i][j]!=1)continue;
				ll k,last=0,ub=1;
				if(i!=0&&j!=0)ub=2;
				ll dis=ceil(D/sqrt(i*i+j*j));
				for(k=1;k;k++){
					if(k*i>w||k*j>h)break;
					ll L=w-k*i+1;ll R=h-k*j+1;
					(ans+=L*R%P*(1ll*(f[dis][k][n-1]-f[dis][k-1][n-1]))*ub%P)%=P;
				}
			}
		printf("%lld\n",(ans+P)%P);
	}
	return 0;
}

标签:include,frac,OI,leq,ll,计数,枚举,ans,集训营
来源: https://www.cnblogs.com/QuantAsk/p/15375017.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有