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;
}

浙公网安备 33010602011771号