题意:
给出一个n*n的矩阵,要求在每个位置涂上黑/白色,要求满足:任意相邻的两行,其颜色要么完全相同,要么完全相反。任意相邻的两列,其颜色也要么相同要么完全相反。
且这个矩形中,不存在任意一个大小大于等于k的同色矩形。
分析:
很简单的DP水题。。。。
我们可以把这个矩形的的每一行设一个值 ,每一列设定一个值 。其中
然后对于格子 其颜色就是: 。
可以保证这样一定满足前两个条件。
然后就是要满足第3个条件。
无非就是 中最长的一段连续相同的值和 中最长的一段连续相同的值的乘积不超过k
就可以用dp求出:对于最长连续相同长度刚好为 的,总长度为n的01序列的方案数。
发现这个刚好为x其实不便表示,所以可以用一下差分的思想:求出最长长度不超过x的方案数,设为 ,然后我们要的就是 。这样就排除了所有长度未达到x的方案。
然后这个dp就非常简单了
设
表示前i个位置,最长连续相同不超过j的方案数。
然后
代码28行。。。算是我做过的最简单的E题了。。。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define SF scanf
#define PF printf
#define MAXN 510
#define MOD 998244353
using namespace std;
typedef long long ll;
int n,k;
ll dp[MAXN][MAXN],res,ans[MAXN];
int main(){
SF("%d%d",&n,&k);
for(int i=1;i<=n;i++){
dp[i][0]=1;
for(int j=1;j<=n;j++)
for(int k=1;k<=min(j,i);k++)
dp[i][j]=(dp[i][j]+dp[i][j-k])%MOD;
}
for(int i=1;i<=n;i++)
ans[i]=(dp[i][n]-dp[i-1][n]+MOD)%MOD;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i*j<k)
res=(res+ans[i]*ans[j])%MOD;
PF("%I64d",res*2ll%MOD);
}