Miraclys

一言(ヒトコト)

洛谷P3146 [USACO16OPEN]248 G

\(\Large\textbf{Description: } \large{有n个数的序列,每次可以合并相邻的两个相同的数,得到的一个数原数加一,输出最大能合并多大。(2 \leq n \leq 248)}\\\)

\(\Large\textbf{Solution: } \large{一道典型的区间DP。我们可以枚举合并区间的长度与起点还有中间断点,然后同时更新答案。值得注意的是,最大值并不一定是\text{f[1][n]}。\\}\)

\(\Large\textbf{Code: }\)

#include <cstdio> 
#include <algorithm>
#define LL long long
#define gc() getchar()
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
using namespace std;
const int N = 255;
int n, ans, a, f[N][N];

inline int read() {
	char ch = gc();
	LL ans = 0;
	while (ch > '9' || ch < '0') ch = gc();
	while (ch >= '0' && ch <= '9') ans = (ans << 1) + (ans << 3) + ch - '0', ch = gc();
	return ans;		
}

int main() {
	n = read();
	rep(i, 1, n) a = read(), f[i][i] = a;
	rep(i, 2, n) 
		for (int j = 1; j + i - 1 <= n; ++j) {
			int en = i + j - 1;
			rep(k, j, en - 1) 
				if (f[j][k] == f[k + 1][en] && f[j][k] != 0 && f[k + 1][en] != 0) { f[j][en] = max(f[j][en], f[j][k] + 1); ans = max(ans, f[j][k] + 1); } 
		}
	printf("%d\n", ans);
	return 0;
} 
posted @ 2020-03-12 15:43  Miraclys  阅读(104)  评论(0编辑  收藏  举报

关于本博客样式

部分创意和图片借鉴了

BNDong

的博客,在此感谢