【洛谷】题解 P3205 【[HNOI2010]合唱队】

注意答案对19650827取模。。。

经典的区间DP状态和转移方程

F[l][r]表示当前最后一个添加的人是l的方案数

G[l][r]表示当前最后一个添加的人是r的方案数

f[l][r]=f[l+1][r] (a[l]<a[l+1]) +g[l+1][r] (a[l]<a[r])

g[l][r]=f[l][r-1] (a[l]<a[r]) +g[l][r-1] (a[r-1]<a[r])

// luogu-judger-enable-o2
//#define LOCAL
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <bits/stdc++.h>

#define INF 0x3f
#define ull unsigned long long
#define ll long long
#define FOR(a, b, n) for(int a = b; b >= n ? a >= n : a <= n; b >= n ? a-- : a++)
#define M(a, n) memset(a, n, sizeof(a));
#define S(n) scanf("%d", &n)
#define P(n) printf("%d", n)
#define G(n) getline(cin, n)
#define PI acos(-1.0)

using namespace std;

const int NR = 1006;

inline int read()  {
   	int s = 0, w = 1;
   	char ch = getchar();
   	while(ch <= '0' || ch > '9') {
   		if(ch == '-') {
   			w = -1;
   			ch = getchar();
   		}
   	}
   	while(ch >= '0' && ch <= '9') {
   		s = s * 10 + ch - '0';
   		ch = getchar();
   	}
   	return s * w;
}

const int mod = 19650827; 
ll a[NR], f[NR][NR], g[NR][NR], l, r, n; 
inline ll mx(ll x, ll y) { 
	return x < y ? 1 : 0;
} 
int main() { 
	S(n); 
	FOR(i, 1, n)
		S(a[i]); 
	FOR(i, 1, n) 
		f[i][i] = 1; 
	FOR(i, 1, n - 1) 
		FOR(j, 1, n) { 
			if(i + j > n)
				continue; 
			int l = j, r = j + i; 
			f[l][r] = (f[l + 1][r] * mx(a[l], a[l + 1]) + g[l + 1][r] * mx(a[l], a[r])) % mod; 
			g[l][r] = (f[l][r - 1] * mx(a[l], a[r]) + g[l][r - 1] * mx(a[r - 1], a[r])) % mod; 
		} 
	P((f[1][n] + g[1][n]) % mod);
	return 0; 
}

猜你喜欢

转载自blog.csdn.net/jzc20080511/article/details/85853754