Codeforces 1027E Inverse Coloring【DP】
E. Inverse Coloring
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的由一種顏色組成的小矩形。
題解:首先我們假設每行有個係數,每列有一個係數則第i行第j列的顏色為。就可以巧妙的解決第一個要求。假設求出長度n的01串的最長連續0或1的個數為x設為d[x],那個當行最長連續與列最長連續的積小於k就可以滿足要求。對於長度為n的最長連續長度為x的01串可以用差分求出來,設c[x]為長度最長連續長度小於等於x的個數,則d[x]=c[x]-c[x-1]。c[x]可以用dp維護。
設dp[i][j]為長度為i的最長連續小於j的個數,則轉移方程為:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL MOD=998244353;
LL dp[505][505],a[505];
int main()
{
int n,k;printf("%.5f\n",(double)clock()/CLOCKS_PER_SEC);
scanf("%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(i,j); k++)
dp[i][j]=(dp[i][j]+dp[i][j-k])%MOD;
}
for(int i=1; i<=n; i++)
a[i]=(dp[i][n]-dp[i-1][n]+MOD)%MOD;
LL ans=0;
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
if(i*j<k)
ans+=a[i]*a[j]%MOD;
ans=ans*2%MOD;
printf("%lld\n",ans);
}