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;
}