• [HNOI2010] 合唱队


    题目链接:https://www.luogu.org/problemnew/show/P3205
    一个区间DP的题目。

    设计状态为:(dp1[i][j])表示当前区间为([i,j]),而且最后一个放入的在(i)位置,(dp2[i][j])表示当前区间为([i,j]),而且最后一个放入的在(j)位置。

    那么状态转移就是:

    if(a[i]<a[i+1]) 
    	dp1[i][j]+=dp1[i+1][j];
    if(a[i]<a[j])   
    	dp1[i][j]+=dp2[i+1][j];
    if(a[j]>a[i])   
    	dp2[i][j]+=dp1[i][j-1];
    if(a[j]>a[j-1]) 
    	dp2[i][j]+=dp2[i][j-1];
    

    注意初始化有两种qwq:(dp1[i][i]=1)(dp2[i][i]=1),因为是加法原理累加,所以写一个就可以了。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define MAXN 1010
    #define mod 19650827
    using namespace std;
    int n;
    int a[MAXN],dp1[MAXN][MAXN],dp2[MAXN][MAXN];
    int main()
    {
    
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1;i<=n;i++) dp1[i][i]=1;
        for(int i=n-1;i>=1;i--)
        {
            for(int j=i+1;j<=n;j++)
            {
                if(a[i]<a[i+1]) dp1[i][j]+=dp1[i+1][j],dp1[i][j]%=mod;
                if(a[i]<a[j]) dp1[i][j]+=dp2[i+1][j],dp1[i][j]%=mod;
                if(a[j]>a[i]) dp2[i][j]+=dp1[i][j-1],dp2[i][j]%=mod;
                if(a[j]>a[j-1]) dp2[i][j]+=dp2[i][j-1],dp2[i][j]%=mod;
            }
        }
        printf("%d
    ",(dp1[1][n]+dp2[1][n])%mod);
        return 0;
    }
    
  • 相关阅读:
    Minecraft 1.12.2/1.14.4 Mod开发笔记——搭建环境
    Minecraft 1.12.2 Mod开发笔记
    浅谈莫比乌斯反演
    卡迈克尔数
    一些可能会有用的东西(持续更新)
    emacs配置
    CSPS 2020游记
    浅谈KMP
    Atcoder AGC052
    乌班图操作指令(持续更新)
  • 原文地址:https://www.cnblogs.com/fengxunling/p/9920867.html
Copyright © 2020-2023  润新知