zoukankan      html  css  js  c++  java
  • CF1027E Inverse Coloring

    题意:n × n的矩阵,每个位置可以被染成黑/白色。

    一种gay的染色是任意相邻两行的元素,每两个要么都相同,要么都不同。列同理。

    一种gaygay的染色是一种gay的染色,其中没有哪个颜色的子矩阵大小大于等于k。

    求有多少种gaygay的染色。

    解:首先手玩这个gay的染色到底是什么情况。

    然后发现,每种gay的染色都一一对应一种只有第一行第一列的染色。换句话说,决定了第一行第一列,就可以得到唯一一种gay的染色,并且每种gay的染色都可以用这种方式得到。

    然后考虑gaygay的染色,显然,找出第一行最长连续段和第一列最长连续段。这两者的长度乘积 < k即可。

    又由于第一行和第一列有一个公共元素,而黑白又是轮换对称的,所以把第一个格子固定为黑色,最后×2即可。

    DP求出一行的最长连续段恰好为k时方案数。然后前缀和就是最长连续段小于等于k的方案数了。

    枚举第一行的最长连续段,可以得到一个第一列最长连续段的限制。方案数乘起来就行了。

    注意这个限制要对n取min。

    DP这个环节,具体来说,f[i][j][1/0]表示前i个,最大连续段为j,当前有没有长度为j的连续段的方案数。刷表法转移,枚举当前放长为多少的连续段即可。复杂度n3

     1 #include <cstdio>
     2 #include <algorithm>
     3 
     4 const int N = 510, MO = 998244353;
     5 
     6 int f[N][N][2], sum[N];
     7 
     8 inline void add(int &a, const int &b) {
     9     a = (a + b) % MO;
    10     return;
    11 }
    12 
    13 int main() {
    14     int n, k;
    15     scanf("%d%d", &n, &k);
    16     for(int j = 1; j <= n; j++) {
    17         f[0][j][0] = 1;
    18     }
    19     for(int i = 0; i <= n; i++) {
    20         for(int j = 1; j <= n; j++) {
    21             // f[i][j][0/1]
    22             for(int k = 1; k < j && i + k <= n; k++) {
    23                 add(f[i + k][j][0], f[i][j][0]);
    24                 add(f[i + k][j][1], f[i][j][1]);
    25             }
    26             if(i + j <= n) {
    27                 add(f[i + j][j][1], f[i][j][0]);
    28                 add(f[i + j][j][1], f[i][j][1]);
    29             }
    30         }
    31     }
    32     // f[n][i][1]
    33     for(int i = 1; i <= n; i++) {
    34         sum[i] = (f[n][i][1] + sum[i - 1]) % MO;
    35     }
    36 
    37     int ans = 0;
    38     for(int i = 1; i <= n; i++) {
    39         int t = std::min(n, (k - 1) / i);
    40         add(ans, 1ll * f[n][i][1] * sum[t] % MO);
    41     }
    42 
    43     printf("%d", ans * 2 % MO);
    44     return 0;
    45 }
    AC代码
  • 相关阅读:
    继承String?
    java sizeof
    什么是java序列化,如何实现java序列化?
    负载均衡的时候如何实现相同的session被分配到同一个服务器
    如何实现session共享
    java 字符串排序
    forward和redirect的区别
    数字签名 数字证书
    找出数组中重复次数最多的元素并打印
    get和post区别
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10351068.html
Copyright © 2011-2022 走看看