【Luogu】P3205合唱队(区间DP)

  题目链接

  通过这题我发现我已经不会DP了

  区间DP,f[i][j]是从左面转移来的,d[i][j]是从右面转移来的

  然后DP方程是

if(q[i]<q[i+1])    f[i][j]+=f[i+1][j];
if(q[i]<q[j])    f[i][j]+=d[i+1][j];
f[i][j]%=mod;
if(q[i]<q[j])    d[i][j]+=f[i][j-1];
if(q[j]>q[j-1])    d[i][j]+=d[i][j-1];
d[i][j]%=mod;

  然后就是代码啦

  

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<cstdlib>
#define maxn 1020
#define mod 19650827
using namespace std;
inline long long read(){
    long long num=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-')    f=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        num=num*10+ch-'0';
        ch=getchar();
    }
    return num*f;
}

int rai[maxn],dow[maxn];
int q[maxn];
int f[maxn][maxn];
int d[maxn][maxn];

int main(){
    int n=read();
    for(int i=1;i<=n;++i)    q[i]=read();
    for(int i=1;i<=n;++i)    f[i][i]=1;
    for(int len=2;len<=n;++len){
        for(int i=1;i+len-1<=n;++i){
            int j=i+len-1;
            if(q[i]<q[i+1])    f[i][j]+=f[i+1][j];
            if(q[i]<q[j])    f[i][j]+=d[i+1][j];
            f[i][j]%=mod;
            if(q[i]<q[j])    d[i][j]+=f[i][j-1];
            if(q[j]>q[j-1])    d[i][j]+=d[i][j-1];
            d[i][j]%=mod;
        }
    }
    printf("%d",(f[1][n]+d[1][n])%mod);
    return 0;
}

 

posted @ 2018-01-19 13:27  Konoset  阅读(147)  评论(0编辑  收藏  举报