题解: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;
}
posted @ 2024-11-02 09:22  liukejie  阅读(1)  评论(0编辑  收藏  举报