DP Ⅲ

Zuma

区间dp板题,判断以下首尾是否相同即可。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
template <typename T> inline void read(T &x)
{
	x = 0; bool f = 0; char ch = getchar();
	while('0' > ch || ch > '9') { if(ch == '-') f = !f; ch = getchar(); }
	while('0' <= ch && ch <= '9') { x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar(); }
	x = f ? -x : x; return;
}
template <typename T> inline void print(T x)
{
	if(x < 0) putchar('-'), x = -x;
	if(x > 9) print(x / 10);
	putchar(x % 10 + '0'); return;
}
const int N = 510;
int f[N][N], a[N], n;
int main()
{
	read(n);
	for(int i = 1; i <= n; i ++) read(a[i]);
	memset(f, 0x3f, sizeof(f));
	for(int i = 1; i <= n; i ++) f[i][i] = 1;
	for(int len = 2; len <= n; len ++)
	{
		for(int i = 1; i <= n - len + 1; i ++)
		{
			int j = i + len - 1;
			for(int k = i; k < j; k ++)
			{
				if(a[i] == a[j])
				{
					if(i == j - 1) f[i][j] = 1;
					else f[i][j] = min(f[i][j], f[i + 1][j - 1]);
				}
				f[i][j] = min(f[i][j], f[i][k] + f[k + 1][j]);
			}
		}
	}
	print(f[1][n]);
	return 0;
}

P3205 [HNOI2010] 合唱队

注意到大区间的状态是由小区间的状态转移过来的,所以可以用区间dp。

用f[i][j]表示达成理想区间,最后进来的是i的原序列个数。

用g[i][j]表示达成理想区间,最后进来的是j的原序列个数。

考虑f数组。f[i][j]一定是由f[i + 1][j]或g[i + 1][j]转移而来,条件是a[i] < a[i + 1]或a[i] < a[j]。

考虑g数组。g[i][j]一定是由f[i][j - 1]或g[i][j - 1]转移而来,条件是a[j] > a[i]或a[j] > a[j - 1]。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
template <typename T> inline void read(T &x)
{
	x = 0; bool f = 0; char ch = getchar();
	while('0' > ch || ch > '9') { if(ch == '-') f = !f; ch = getchar(); }
	while('0' <= ch && ch <= '9') { x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar(); }
	x = f ? -x : x; return;
}
template <typename T> inline void print(T x)
{
	if(x < 0) putchar('-'), x = -x;
	if(x > 9) print(x / 10);
	putchar(x % 10 + '0'); return;
}
const int N = 1010, mod = 19650827;
int n, a[N], f[N][N], g[N][N];
int main()
{
	read(n);
	for(int i = 1; i <= n; i ++) read(a[i]);
	for(int i = 1; i <= n; i ++) f[i][i] = 1;
	for(int len = 2; len <= n; len ++)
	{
		for(int i = 1; i <= n - len + 1; i ++)
		{
			(f[i][i + len - 1] += f[i + 1][i + len - 1] * (a[i] < a[i + 1])) %= mod;
			(f[i][i + len - 1] += g[i + 1][i + len - 1] * (a[i] < a[i + len - 1])) %= mod;
			(g[i][i + len - 1] += f[i][i + len - 2] * (a[i + len - 1] > a[i])) %= mod;
			(g[i][i + len - 1] += g[i][i + len - 2] * (a[i + len - 1] > a[i + len - 2])) %= mod;
		}
	}
	print((f[1][n] + g[1][n]) % mod);
	return 0;
}
posted @   小队长wtz  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示