E. Inverse Coloring
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given a square board, consisting of nn rows and nn columns. Each tile in it should be colored either white or black.
Let's call some coloring beautiful if each pair of adjacent rows are either the same or different in every position. The same condition should be held for the columns as well.
Let's call some coloring suitable if it is beautiful and there is no rectangle of the single color, consisting of at least kk tiles.
Your task is to count the number of suitable colorings of the board of the given size.
Since the answer can be very large, print it modulo 998244353998244353.
Input
A single line contains two integers nn and kk (1≤n≤5001≤n≤500, 1≤k≤n21≤k≤n2) — the number of rows and columns of the board and the maximum number of tiles inside the rectangle of the single color, respectively.
Output
Print a single integer — the number of suitable colorings of the board of the given size modulo 998244353998244353.
Examples
input
Copy
1 1
output
Copy
0
input
Copy
2 3
output
Copy
6
input
Copy
49 1808
output
Copy
359087121
Note
Board of size 1×11×1 is either a single black tile or a single white tile. Both of them include a rectangle of a single color, consisting of 11 tile.
Here are the beautiful colorings of a board of size 2×22×2 that don't include rectangles of a single color, consisting of at least 33 tiles:
The rest of beautiful colorings of a board of size 2×22×2 are the following:
题意: 现在给你一个n*n的方格,现在要对每个格子染色,只有黑白两种颜色,但是要保证一个原则就是相邻的两行或者两列,必须保证完全一样,或者完全不一样, 现在你要求的就是满足没有同色的矩形大于等于k 的方案个数。
思路: 这里给的这个条件很强的,就是任意的两行两列,完全相同或者完全不相同,那么我们如果确定了任意的一行和一列,那么就相当于确定了整个矩阵。那么满足条件的矩阵是怎样的呢,肯定是不能出现一行0(白色)的个数和一列的0的个数相乘大于等于k,所以我们要维护的就是行列中最大相同颜色段的长度的乘积是小于k的,那么我们可以dp出来长度为pos的序列(一行)中最长相同颜色的长度不超过j的方案数,我们用 dp[ pos ][ len ] 表示长度为pos 最长相同颜色不超过len的方案数,然后查分一下,就可以求出长度为pos 的序列中相同颜色数为len 的方案数。 然后问题就解决了。
一个小垃圾dp 搞了我一晚上。。。不过这个题还是蛮好的。柑橘。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int N =505;
ll dp[N][N];
int n,k;
int main()
{
scanf("%d %d",&n,&k);
dp[0][0]=1;
for(int pos=1;pos<=n;pos++){
for(int len=1;len<=pos;len++){
int down=pos-len;
int up=pos-1;
for(int x=down;x<=up;x++){
dp[pos][len]+=dp[x][min(x,len)];
dp[pos][len]%=mod;
}
}
}
/*
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cout<<dp[i][j]<<" ";
}
cout<<endl;
}
*/
for(int i=n;i>=1;i--){
dp[n][i]=(dp[n][i]-dp[n][i-1]+mod)%mod;
}
ll ans=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i*j<k){
ans+=dp[n][i]*dp[n][j];
ans%=mod;
}
}
}
ans=ans*2%mod;
printf("%lld\n",ans);
return 0;
}