码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ1996 合唱队 区间DP

时间:2016-07-24 22:40:34      阅读:336      评论:0      收藏:0      [点我收藏+]

标签:

OJ地址:http://www.lydsy.com/JudgeOnline/problem.php?id=1996

设dp(i,j,k)代表在理想结果中[i,j]段最后添加的是i或j(k=0or1)

要注意的一点是程序会计算两次i=j时的情况 要特殊判断

数据不大 我写的是记忆化搜索 改成递推会更快一点

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 const int maxn=1000+10;
 6 const int mod=19650827;
 7 int N,A[maxn],v[maxn][maxn][2];
 8 long mem[maxn][maxn][2];
 9 long DP(int i,int j,int k){
10     if(v[i][j][k]) return mem[i][j][k];
11     v[i][j][k]=1;
12     long& ans=mem[i][j][k]=0;
13     if(i==j) return ans=(k==0?1:0);
14     if(k==0){
15         if(A[j]>A[i]) ans+=DP(i+1,j,1),ans%=mod;
16         if(A[i+1]>A[i]) ans+=DP(i+1,j,0),ans%=mod;
17     }else if(k==1){
18         if(A[j-1]<A[j]) ans+=DP(i,j-1,1),ans%=mod;
19         if(A[i]<A[j]) ans+=DP(i,j-1,0),ans%=mod;
20     }
21     ans%=mod;
22     return ans;
23 
24 }
25 int main()
26 {
27   memset(v,0,sizeof(v));
28   scanf("%d",&N);
29   for(int i=1;i<=N;i++) scanf("%d",&A[i]);
30     printf("%ld",(DP(1,N,0)+DP(1,N,1))%mod);
31   return 0;
32 }

From Linux

BZOJ1996 合唱队 区间DP

标签:

原文地址:http://www.cnblogs.com/gzhonghui/p/5701638.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!