【DP】Codeforces1027E Inverse Coloring

题意:

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

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


分析:

很简单的DP水题。。。。

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

然后对于格子 (i,j) ( i , j ) 其颜色就是: ai xor bj a i   x o r   b j

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

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

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

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

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

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

然后 dp(i,j)=k=1,kmin(j,i)dp(ik,j) d p ( i , j ) = ∑ k = 1 , k ≤ m i n ( j , i ) d p ( i − k , j )

代码28行。。。算是我做过的最简单的E题了。。。

#include
#include
#include
#include
#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"%I64d",res*2ll%MOD);
} 

你可能感兴趣的:(DP)