洛谷:P3205 [HNOI2010]合唱队(dp,提高+/省选-)

题目:

在这里插入图片描述

分析:正在看着题解,突然就自己想出来了,有多少种出法就可以啦。要么从左,要么从右,而且是有限制条件的出,左边出,还是右边出,需要再加一维,和洛谷:P1220 关路灯(提高+/省选-,dp) 一样。

代码:

#include<bits/stdc++.h>
using namespace std;
int A[1001];
int n;
long long D[1001][1001][2];//0表示 左边的要出了   1表示  右边的要出了   
long long f(int x,int y,int z)
{
 if(D[x][y][z]!=-1) return D[x][y][z];
 if(x==y) return 1;
 if(x+1==y){
  if(A[x]<A[y]) {
   return 1;
  } 
  else{
   return 0;
  }
 }
 D[x][y][z]=0;
 if(z==1)
 {
  if(A[y]>A[y-1]) D[x][y][z]+=f(x,y-1,1);
  D[x][y][z]=D[x][y][z]%19650827;
  if(A[y]>A[x]) D[x][y][z]+=f(x,y-1,0);
  D[x][y][z]=D[x][y][z]%19650827;
 }
 if(z==0)
 {
  if(A[x]<A[y]) D[x][y][z]+=f(x+1,y,1);
  D[x][y][z]=D[x][y][z]%19650827; 
  if(A[x]<A[x+1]) D[x][y][z]+=f(x+1,y,0);
  D[x][y][z]=D[x][y][z]%19650827;
 }
 return D[x][y][z];
}
int main()
{
 cin>>n;
 for(int i=0;i<n;i++) cin>>A[i];
 memset(D,-1,sizeof(D)); 
 //cout<<f(0,n-1,0);
 cout<<(f(0,n-1,1)+f(0,n-1,0))%19650827;
}

猜你喜欢

转载自blog.csdn.net/weixin_42721412/article/details/107582555
今日推荐