zoukankan      html  css  js  c++  java
  • BZOJ 1996 合唱队(DP)

    考虑从最后的队形开始依次还原最初的队形。

    对于当前的队形,要么选最左边的,要么选最右边的。 如果选了左边的,那么下次选择的一定是大于它的。右边的同理。

    所以定义dp[mark][l][r]为区间[l,r]的选择状态为mark的方法数。

    然后记忆化搜索一下就可以了。

    # include <cstdio>
    # include <cstring>
    # include <cstdlib>
    # include <iostream>
    # include <vector>
    # include <queue>
    # include <stack>
    # include <map>
    # include <set>
    # include <cmath>
    # include <algorithm>
    using namespace std;
    # define lowbit(x) ((x)&(-x))
    # define pi 3.1415926535
    # define eps 1e-9
    # define MOD 19650827
    # define INF 1000000000
    # define mem(a,b) memset(a,b,sizeof(a))
    # define FOR(i,a,n) for(int i=a; i<=n; ++i)
    # define FO(i,a,n) for(int i=a; i<n; ++i)
    # define bug puts("H");
    # define lch p<<1,l,mid
    # define rch p<<1|1,mid+1,r
    # define mp make_pair
    # define pb push_back
    typedef pair<int,int> PII;
    typedef vector<int> VI;
    # pragma comment(linker, "/STACK:1024000000,1024000000")
    typedef long long LL;
    int Scan() {
        int res=0, flag=0;
        char ch;
        if((ch=getchar())=='-') flag=1;
        else if(ch>='0'&&ch<='9') res=ch-'0';
        while((ch=getchar())>='0'&&ch<='9')  res=res*10+(ch-'0');
        return flag?-res:res;
    }
    void Out(int a) {
        if(a<0) {putchar('-'); a=-a;}
        if(a>=10) Out(a/10);
        putchar(a%10+'0');
    }
    const int N=1005;
    //Code begin...
    
    int dp[2][N][N], a[N];
    
    int dfs(int mark, int l, int r){
        if (~dp[mark][l][r]) return dp[mark][l][r];
        if (l==r) return dp[mark][l][r]=1;
        int res=0;
        if (mark) {
            if (a[l]<a[r]) res+=dfs(0,l,r-1);
            if (r-1!=l&&a[r-1]<a[r]) res+=dfs(1,l,r-1);
        }
        else {
            if (a[r]>a[l]) res+=dfs(1,l+1,r);
            if (l+1!=r&&a[l+1]>a[l]) res+=dfs(0,l+1,r);
        }
        return dp[mark][l][r]=res%MOD;
    }
    int main ()
    {
        mem(dp,-1);
        int n;
        scanf("%d",&n);
        FOR(i,1,n) scanf("%d",a+i);
        printf("%d
    ",(dfs(0,1,n)+dfs(1,1,n))%MOD);
        return 0;
    }
    View Code
  • 相关阅读:
    鼠标放在图片上出现提示
    NSIS调用dll
    IIS7 CMD命令
    NSIS检测
    NSIS修改文件夹访问权限
    NSIS——检测IIS是否安装及版本
    NSIS——检测SQL Server安装版本
    NSIS使用技巧集合
    提供修复界面的NSIS安装包
    NSIS MUI教程
  • 原文地址:https://www.cnblogs.com/lishiyao/p/6648555.html
Copyright © 2011-2022 走看看