Codeforces 1733E - Conveyor(DP)

喜闻乐见降智环节。

首先,同一不会有两个史莱姆位于同一格子上。证明显然。

考虑计算 \(t\) 时刻内有多少史莱姆经过了 \((x,y)\),再计算 \(t-1\) 时刻内有多少史莱姆经过了 \((x,y)\),判断二者是否相等即可。考虑如何求前者。设 \(dp_{x,y}\) 表示有多少史莱姆经过了 \((x,y)\),我们惊奇地发现,在经过 \((x,y)\) 的史莱姆中,刚好有 \(\lfloor\dfrac{dp_{x,y}}{2}\rfloor\) 个向下走,\(\lceil\dfrac{dp_{x,y}}{2}\rceil\) 个向右走,于是顺着推过去即可。初始状态 \(dp_{0,0}=t-x-y+1\)

时间复杂度 \(O(Tn^2)\)

const int MAXN=120;
ll dp[MAXN+5][MAXN+5];
ll calc(ll t,int x,int y){
	if(x+y>t)return 0;memset(dp,0,sizeof(dp));dp[0][0]=t-x-y+1;
	for(int i=0;i<120;i++)for(int j=0;j<120;j++){
		dp[i][j+1]+=dp[i][j]+1>>1;
		dp[i+1][j]+=dp[i][j]>>1;
	}return dp[x][y];
}
int main(){
#ifdef LOCAL
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
#endif
	int qu;scanf("%d",&qu);
	while(qu--){
		ll t;int x,y;scanf("%lld%d%d",&t,&x,&y);
		if(t==0)printf("%s\n",(x|y)?"NO":"YES");
		else printf("%s\n",(calc(t,x,y)==calc(t-1,x,y))?"NO":"YES");
	}
	return 0;
}
posted @ 2022-12-23 20:17  tzc_wk  阅读(17)  评论(0编辑  收藏  举报