zoukankan      html  css  js  c++  java
  • P3205 [HNOI2010]合唱队

    P3205 [HNOI2010]合唱队

    题解

    区间DP唉

    不会写怎么办QAQ

    先暴搜

    暴力:

    根据理想队形找原序列,找第一个人不好找,但是可以确定最后一个人是谁,然后就可以一次推测前一个人,知道搜出一个合法序列

    显然,最后一个人只可能是理想序列的最左端或最右端

    然后在剩下的区间里面,找到合法的下一个人,继续搜,知道搜到只剩一个人的区间,判断一下合不合法,就可以判断能否得到一个合法序列

    为了有效避免一开始的分类讨论(也就是从最左端开始还是从最右端开始算最后一个)

    我们默认最后一个人的标号为 0 ,因为此时第0个人的身高为0,在整个区间最左端,肯定比左右区间的人都矮

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    
    using namespace std;
    
    typedef long long ll;
    
    inline int read()
    {
        int ans=0;
        char last=' ',ch=getchar();
        while(ch<'0'||ch>'9') last=ch,ch=getchar();
        while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
        if(last=='-') ans=-ans;
        return ans;
    }
    
    const int mod=19650827;
    int n;
    int a[1005];
    ll ans=0;
    
    ll dfs (int now,int l,int r)
    //当前搜索的人的标号,下面要搜索的区间[l,r] 
    {
        if(l==r) return (now>l&&a[now]>a[l])||(now<l&&a[now]<a[l]);
        //区间只剩一个人喽,也要最后判断一下 
        if(now>r&&a[now]<a[l]&&a[now]<a[r]) return 0;
        if(now<l&&a[now]>a[l]&&a[now]>a[r]) return 0;
        //不合法,直接计0 
        ll res=0;
        if(now>r&&a[now]>a[l]||now<l&&a[now]<a[l]) 
           res=res+dfs(l,l+1,r)%mod;
        if(now>r&&a[now]>a[r]||now<l&&a[now]<a[r])
           res=res+dfs(r,l,r-1)%mod;
        return res%mod;
        
    }
    
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++) a[i]=read();
        ans=0;
        ans=ans+dfs(0,1,n)%mod;
        printf("%lld
    ",ans);
        
        return 0;
    }

    记忆化:

    不好意思我 WA 了几个点

    考虑区间DP:

    设置两个数组:

    f[ i ][ j ] 区间 [ i , j ] 最后一个选择左端点的合法序列数

    g[ i ][ j ] 区间 [ i , j ] 最后一个选择右端点的合法序列数

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    
    using namespace std;
    
    typedef long long ll;
    
    inline int read()
    {
        int ans=0;
        char last=' ',ch=getchar();
        while(ch<'0'||ch>'9') last=ch,ch=getchar();
        while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
        if(last=='-') ans=-ans;
        return ans;
    }
    
    const int mod=19650827,maxn=214748360,minn=-1;
    int n;
    int a[1005];
    ll f[1005][1005],g[1005][1005];
    
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++) a[i]=read();
        a[0]=3000;
        for(int i=1;i<=n;i++) f[i][i]=1;
    
        for(int l=2;l<=n;l++)
          for(int i=1;i+l-1<=n;i++)
          {
              int j=i+l-1;
            f[i][j]=(f[i+1][j]*(a[i]<a[i+1])%mod+g[i+1][j]*(a[i]<a[j])%mod)%mod;
            g[i][j]=(f[i][j-1]*(a[j]>a[i])%mod+g[i][j-1]*(a[j]>a[j-1])%mod)%mod;
          }
        
        printf("%lld
    ",(f[1][n]+g[1][n])%mod);
        
        return 0;
    }
  • 相关阅读:
    js统一设置富文本中的图片宽度
    springboot 使用Filter
    js判断当前浏览器
    es安装ik后报错无法启动 read write
    logback Filter LevelFilter ThresholdFilter
    使用vue构建一个可视化大数据平台
    常用ES6-ES10知识点总结
    常见的web安全问题总结
    web性能优化指南
    使用node+express+mongodb实现用户注册、登录和验证功能
  • 原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/11535601.html
Copyright © 2011-2022 走看看