• 【luogu3205】【bzoj1996】 [HNOI2010]合唱队 [区间dp]


    P3205 [HNOI2010]合唱队

    bzoj1996  

    对从第二个人开始的每个人,如果他比前面那个人高(H较大),那么将他插入当前队形的最右边。如果他比前面那个人矮(H较小),那么将他插入当前队形的最左边。

    给定一串序列,问有多少种初始序列经过如题操作可以得到此序列。

    很容易想到每一个状态是由最后一个决策决定的

    所以就是区间dp的一个经典状态 f[l,r]由最后一步决定 枚举长度

    如果a[l]<[r]就由两种状态转移过来 然后是l和l+1比较 r和r-1比较 来判断决策

    具体靠代码感性理解

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<queue>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<stack>
     7 #include<algorithm>
     8 using namespace std;
     9 #define ll long long
    10 #define rg register
    11 const int N=1000+5,inf=0x3f3f3f3f,P=19650827;
    12 int n,a[N],f[N][N][2];
    13 template <class t>void rd(t &x)
    14 {
    15     x=0;int w=0;char ch=0;
    16     while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    17     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    18     x=w?-x:x;
    19 }
    20 
    21 int main()
    22 {
    23     freopen("in.txt","r",stdin);
    24     //freopen("nocows.out","w",stdout);
    25     rd(n);
    26     for(rg int i=1;i<=n;++i) rd(a[i]),f[i][i][0]=1;
    27     for(rg int i=2;i<=n;++i)
    28     for(rg int l=1;l<n&&l+i-1<=n;++l)
    29     {
    30         int r=i+l-1;
    31         if(a[l]<a[l+1]) f[l][r][0]=(f[l][r][0]+f[l+1][r][0])%P;
    32         if(a[r]>a[r-1]) f[l][r][1]+=f[l][r-1][1];
    33         if(a[l]<a[r]) f[l][r][1]+=f[l][r-1][0];
    34         if(a[l]<a[r]) f[l][r][0]+=f[l+1][r][1];
    35         f[l][r][0]%=P,f[l][r][1]%=P;
    36     }
    37     printf("%d",(f[1][n][0]+f[1][n][1])%P);
    38     return 0;
    39 }
  • 相关阅读:
    eBay要怎么转型?
    一张图让你看懂javascript各类型的关系
    闭包概念,匿名函数
    浅析Javascript闭包的特性
    深入理解JavaScript闭包(closure)
    深入理解JavaScript作用域和作用域链
    WPF 学习笔记(一)
    ChromiumWebBrowser flash不能自动播放问题解决方案
    饱含辛酸开发 WPF CustomControl
    KMP算法备忘
  • 原文地址:https://www.cnblogs.com/lxyyyy/p/10885818.html
Copyright © 2020-2023  润新知