SCOI2009 粉刷匠 【动态规划】

个人感觉是,像这类线性dp,只要把状态想出来了,转移轻而易举

这题我感觉我多想想也能想出来,但是想到一般看题解去了

dp[i][j][k][0/1/2]表示在第i行第j列,涂了k次,当前块涂的是0/1,或者不涂(2),i这一维度可以滚掉

转移:

        dp[i & 1][j][k][2] = (j == 0 ? std::max(dp[!(i & 1)][m - 1][k][2], std::max(dp[!(i & 1)][m - 1][k][0], dp[!(i & 1)][m - 1][k][1])) : std::max(dp[i & 1][j - 1][k][0], std::max(dp[i & 1][j - 1][k][1], dp[i & 1][j - 1][k][2])));
        dp[i & 1][j][k][0] = (j == 0 ? std::max(dp[!(i & 1)][m - 1][k - 1][0], std::max(dp[!(i & 1)][m - 1][k - 1][1], dp[!(i & 1)][m - 1][k - 1][2])) : std::max(dp[i & 1][j - 1][k][0], std::max(dp[i & 1][j - 1][k - 1][1], dp[i & 1][j - 1][k - 1][2]))) + (map[i][j] == 0);
        dp[i & 1][j][k][1] = (j == 0 ? std::max(dp[!(i & 1)][m - 1][k - 1][1], std::max(dp[!(i & 1)][m - 1][k - 1][0], dp[!(i & 1)][m - 1][k - 1][2])) : std::max(dp[i & 1][j - 1][k][1], std::max(dp[i & 1][j - 1][k - 1][0], dp[i & 1][j - 1][k - 1][2]))) + (map[i][j] == 1);

因为这题拖得有点久,所以写的急了点,代码很丑(一行能写这么多是我妹想到的)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define gi get_int()
const int MAXN = 100;
int get_int()
{
  int x = 0, y = 1;
  char ch = getchar();
  while (!isdigit(ch) && ch == '-')
    ch = getchar();
  if (ch == '-')
    y = -1, ch = getchar();
  while (isdigit(ch))
    x = x * 10 + ch - '0', ch = getchar();
  return x * y;
}

int map[MAXN][MAXN], sum[MAXN][MAXN][2], dp[2][MAXN][2501][3];

int main()
{
  freopen("code.in", "r", stdin);
  freopen("code.out", "w", stdout);

  int n = gi, m = gi, t = gi;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      char ch;
      std::cin >> ch;
      map[i][j] = ch - 48;
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++)
    for (int j = 0; j < m; j++) {
      for (int k = 1; k <= t; k++) {
        dp[i & 1][j][k][2] = (j == 0 ? std::max(dp[!(i & 1)][m - 1][k][2], std::max(dp[!(i & 1)][m - 1][k][0], dp[!(i & 1)][m - 1][k][1])) : std::max(dp[i & 1][j - 1][k][0], std::max(dp[i & 1][j - 1][k][1], dp[i & 1][j - 1][k][2])));
        dp[i & 1][j][k][0] = (j == 0 ? std::max(dp[!(i & 1)][m - 1][k - 1][0], std::max(dp[!(i & 1)][m - 1][k - 1][1], dp[!(i & 1)][m - 1][k - 1][2])) : std::max(dp[i & 1][j - 1][k][0], std::max(dp[i & 1][j - 1][k - 1][1], dp[i & 1][j - 1][k - 1][2]))) + (map[i][j] == 0);
        dp[i & 1][j][k][1] = (j == 0 ? std::max(dp[!(i & 1)][m - 1][k - 1][1], std::max(dp[!(i & 1)][m - 1][k - 1][0], dp[!(i & 1)][m - 1][k - 1][2])) : std::max(dp[i & 1][j - 1][k][1], std::max(dp[i & 1][j - 1][k - 1][0], dp[i & 1][j - 1][k - 1][2]))) + (map[i][j] == 1);
      }
    }
  }
  int ans = 0;
  for (int i = 1; i <= t; i++) {
    ans = std::max(ans, std::max(dp[(n - 1) & 1][m - 1][i][0], std::max(dp[(n - 1) & 1][m - 1][i][1], dp[(n - 1) & 1][m - 1][i][2])));
  }
  std::cout << ans;

  return 0;
}
posted @ 2021-05-24 10:38  enisp  阅读(32)  评论(0)    收藏  举报