欲望以提升热忱,毅力以磨平高山!|

XichenOC

园龄:1个月粉丝:4关注:0

📂题解
🔖DP
2025-01-20 19:30阅读: 3评论: 0推荐: 0

P3205 [HNOI2010] 合唱队

P3205 [HNOI2010] 合唱队

题目翻译:

太简单了,就不翻译了

思路:

一道很不像区间\(dp\)的区间\(dp\),我们知道,不管是理想队形,还是初始队形,其大小都为\(n\),那我们令\(i,j\)表示已经加入的队形在最终队形的\(i\)\(j\)中则令\(f[i][j][0]\)表示把点从左边加入第\(i\)人,而\(f[i][j][1]\)表示将第\(j\)人从右边加入。由此可以推出三种情况:

先令第\(i\)个人的高度为\(h[i]\)

\(1.\)若上一个人是第\(i+1\)个,则有\(h[i]<h[i+1]\)那也就是说它比上一个人矮,那就应该加到右边。

\[$dp[i][j][0]+=dp[i+1][j][0] (h[i]<h[i+1])$ \]

\(2.\)若上一个人是\(j\)那它上次就是从右边加入,而\(h[i]<h[j]\),则它比上一个矮,那它就应该从左边加入,则:

\[$dp[i][j][0]+=dp[i+1][j][1] (h[i]<h[j])$ \]

\(3.\)若上一个人是\(j-1\)而我的高度\(h[j]>h[j-1]\),那我比上一个高,就应该从右边加入,则:

\[$dp[i][j][1]+=dp[i][j-1][1] (h[j-1]<h[j])$ \]

\(4.\)若上一个人是\(i\),且我的高度\(h[j]>h[i]\)则我还是因该从右边加入,则

\[$dp[i][j][1]+=dp[i][j-1][0] (h[j]>h[i])$ \]

为了保证\(dp\)时所有子区间已经\(dp\),则我们根据长度\(dp\)即可

完整代码:

#include<bits/stdc++.h>
using namespace std;
const int N=2000;
const int P=19650827;
int dp[N][N][2];
int h[N];
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>h[i];
        dp[i][i][0]=1;
    }
    for(int len=1;len<=n;len++){
        for(int i=1;i<=n-len+1;i++){
            int j=i+len-1;
            if(h[i]<h[i+1])dp[i][j][0]+=dp[i+1][j][0];
            if(h[i]<h[j])dp[i][j][0]+=dp[i+1][j][1];
            if(h[j]>h[i])dp[i][j][1]+=dp[i][j-1][0];
            if(h[j]>h[j-1])dp[i][j][1]+=dp[i][j-1][1];
            dp[i][j][0]%=P;
            dp[i][j][1]%=P;
        }
    }
    cout<<(dp[1][n][0]+dp[1][n][1])%P<<endl;
}

区间\(DP\)讲解

本文作者:XichenOC

本文链接:https://www.cnblogs.com/XichenOC/p/18682393

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   XichenOC  阅读(3)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起