bzoj1996

区间dp

其实我们发现对于一段区间我们是这样构造的,每次我们会向两端放数,这样就有四种情况,且必须满足题意,初值是dp[i][i][0]=1,因为第一个人只有一种放法,不分左右。其实看见dp[i][i][0/1]=1时答案是16就改初值

#include<bits/stdc++.h>
using namespace std;
const int N = 1010, mod = 19650827;
int n;
int h[N], dp[N][N][2];
void up(int &x, int d)
{
    x = (x + d) % mod;
}
int dfs(int l, int r, int f)
{
    if(l == r) return f;
    if(dp[l][r][f] != -1) return dp[l][r][f];
    int &ret = (dp[l][r][f] = 0);
    if(f == 0)
    {
        if(h[l] < h[l + 1]) up(ret, dfs(l + 1, r, f));
        if(h[l] < h[r]) up(ret, dfs(l + 1, r, f ^ 1));
    }
    else
    {
        if(h[r] > h[r - 1]) up(ret, dfs(l, r - 1, f));
        if(h[r] > h[l]) up(ret, dfs(l, r - 1, f ^ 1));
    }
    return ret;
}
int main()
{
    memset(dp, -1, sizeof(dp));
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) scanf("%d", &h[i]);
    printf("%d\n", (dfs(1, n, 0) + dfs(1, n, 1)) % mod);
    return 0;
} 
View Code

 

posted @ 2017-10-19 21:47  19992147  阅读(152)  评论(1编辑  收藏  举报