题解:AT_joi2018ho_c 団子職人 (Dango Maker)
题意
给出一个由 R G W
组成的表格,问你能取出多少串 RGW
。
思路
如果两个团子重合是下面三种情况
RGW R R
G G RGW
W RGW W
我们发现相交的团子在同一条对角线上,不在一条对角线上的互不影响,所以我们设 \(f_{i,j,0/1/2}\) 为选 \([i,j],[i-1,j+1],[i-2,j+1]\) 的最大方案,转移为
\[f_{i,j,0} = \max(f_{i-1,j+1,0},f_{i-1,j+1,1}, f_{i-1,j+1,2})
\]
\[f_{i,j,1} = \max(f_{i-1,j+1,1}, f_{i-1,j+1,0}) + 1
\]
\[f_{i,j,2} = \max(f_{i-1,j+1,2}, f_{i-1,j+1,0}) + 1
\]
\[\text{ans} = \max(f_{i-1,j+1,0},f_{i-1,j+1,1},f_{i-1,j+1,2})
\]
#include <bits/stdc++.h>
using namespace std;
#define rep(i, l, r) for(int i = l; i <= r; ++ i)
#define per(i, r, l) for(int i = r; i >= l; -- i)
const int N = 3010;
char s[N][N];
int f[N][N][4], ans, n, m;
void check(int i, int j)
{
for (; i <= n && j >= 1; ++ i, -- j)
{
int ti = i - 1, tj = j + 1;
f[i][j][0] = max({f[ti][tj][0], f[ti][tj][1], f[ti][tj][2]});
if(i - 1 >= 1 && i + 1 <= n && s[i][j] == 'G' && s[i - 1][j] == 'R' && s[i + 1][j] == 'W')
f[i][j][1] = max(f[ti][tj][1], f[ti][tj][0]) + 1;
if(j - 1 >= 1 && j + 1 <= m && s[i][j] == 'G' && s[i][j - 1] == 'R' && s[i][j + 1] == 'W')
f[i][j][2] = max(f[ti][tj][2], f[ti][tj][0]) + 1;
}
ans += max({f[-- i][++ j][0], f[i][j][1], f[i][j][2]});
}
main()
{
scanf("%d %d", &n, &m);
rep(i, 1, n) scanf("%s", s[i] + 1);
rep(i, 1, m) check(1, i);
rep(i, 2, n) check(i, m);
printf("%d", ans);
return 0;
}