P11216 【MX-J8-T4】2048 题解
这是本蒟蒻的第一篇正式题解。
本题重点在于找到无解序列的充要条件,首先记
一些性质
-
-
-
若
t_i<t_{i+1} ,那么a_i+1\ne a_{i+1} ,这是因为如果a_i+1=a_{i+1} ,那么a_{i+1} 的合成会影响到a_i 的合成。同理,若t_i<t_{i-1} ,那么a_i+1\ne a_{i-1} 。 -
若
t_{i-1}<t_i<t_{i+1} ,那么不可能会有a_{i-1}<a_i<a_{i+1} ,这是因为如果a_{i-1}<a_i<a_{i+1} ,那么首先要合成a_{i+1}-1 ,然后合成a_i-1 ,最后合成a_{i-1} ,这会使a_i-1 无法进一步合成出a_i 。同理,若t_{i-1}>t_i>t_{i+1} ,那么不可能会有a_{i-1}>a_i>a_{i+1} 。
我们容易发现,这些性质已经充要,我们来考虑如何 dp。
DP
考虑到性质 1 和性质 4,可以发现出现时间最小的位置只能是
设
AC Code
#include<bits/stdc++.h>
using namespace std;
int T,mod,n,x,dp[305][305][305],f[305][305][305],g[305][305][305],sum[305][305];
void add(int &x,int y){
(x+=y)%=mod;
}
void fun(int n,int lx,int rx,int res){//计算贡献
add(sum[n][lx],res),add(sum[n][rx+1],mod-res);
}
int main(){
scanf("%d%d",&T,&mod);
dp[0][0][0]=g[0][0][0]=f[0][0][0]=1,fun(1,1,1,1);
for(int i=1;i<300;i++)
for(int j=0;j<=i;j++)
for(int k=0;k<=i;k++)if(j+k){
if(j)add(dp[i][j][k],f[i-1][j-1][k]);
if(k)add(dp[i][j][k],g[i-1][j][k-1]);
f[i][j][k]=g[i][j][k]=dp[i][j][k],fun(i+1,max(j,k)+1,i+1,dp[i][j][k]);
if(j+1<=k-2)fun(i+1,k,k,dp[i][j][k]*2LL*((k-2)-(j+1)+1)%mod); //考虑到对称性直接*2即可
if(j)add(f[i][j][k],f[i][j-1][k]);
if(k)add(g[i][j][k],g[i][j][k-1]);
}
for(int i=1;i<=300;i++)for(int j=1;j<=300;j++)add(sum[i][j],sum[i][j-1]);
for(int i=1;i<=300;i++)for(int j=1;j<=300;j++)add(sum[i][j],sum[i][j-1]);
while(T--)scanf("%d%d",&n,&x),printf("%d\n",sum[n][x-1]);
return 0;
}
如有表达不清可以在评论区里交流讨论。