当前位置: 代码迷 >> 综合 >> 【DP】Codeforces1027E Inverse Coloring
  详细解决方案

【DP】Codeforces1027E Inverse Coloring

热度:129   发布时间:2023-09-27 06:34:47.0

题意:

给出一个n*n的矩阵,要求在每个位置涂上黑/白色,要求满足:任意相邻的两行,其颜色要么完全相同,要么完全相反。任意相邻的两列,其颜色也要么相同要么完全相反。

且这个矩形中,不存在任意一个大小大于等于k的同色矩形。


分析:

很简单的DP水题。。。。

我们可以把这个矩形的的每一行设一个值aiai,每一列设定一个值bibi。其中ai,bi=01ai,bi=0或1

然后对于格子(i,j)(i,j)其颜色就是:ai xor bjaixorbj

可以保证这样一定满足前两个条件。

然后就是要满足第3个条件。

无非就是aa中最长的一段连续相同的值和 b 中最长的一段连续相同的值的乘积不超过k

就可以用dp求出:对于最长连续相同长度刚好为xx的,总长度为n的01序列的方案数。

发现这个刚好为x其实不便表示,所以可以用一下差分的思想:求出最长长度不超过x的方案数,设为 d p x ,然后我们要的就是dpx?dpx?1dpx?dpx?1。这样就排除了所有长度未达到x的方案。

然后这个dp就非常简单了
dp(i,j)dp(i,j)表示前i个位置,最长连续相同不超过j的方案数。

然后dp(i,j)=k=1,kmin(j,i)dp(i?k,j)dp(i,j)=∑k=1,k≤min(j,i)dp(i?k,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);
} 
  相关解决方案