洛谷 P1091 NOIP 2004 合唱队形(动态规划)
2017-07-24 09:24
113 查看
题目适合已经有一定动态规划基础的去做,如果从未了解过动态规格请看我的另一篇博客:
love_phoebe的博客 求单调递增最长子序列
排合唱队形就是中间高两边递减,给出思路:
求每一个位置i的两个值:
一个是从0到末尾的最长递增子序列dpl[i]
dpl[0]=1; for(i=1;i<N;i++){ int max=0,w; for(w=0;w<i;w++){ if(a[w]<a[i]&&dpl[w]>max)max=dpl[w]; } dpl[i]=max+1; }
一个是从末尾到0的最长递增子序列dpr[i]
dpr[N-1]=1; for(i=N-2;i>=0;i--){ int max=0,w; for(w=i+1;w<N;w++){ if(a[i]>a[w]&&dpr[w]>max)max=dpr[w]; } dpr[i]=max+1; }
对于位置i,dpl[i]是0到i的最长递增子序列,dpr[i]是i到末尾的最长递减子序列
那么位置i需要的人数便是sum[i]=dpl[i]+dpr[i]-1(减一是因为两次都把i算在内)
最后求sum[]数组的最大值便是所需的最多人数,用总人数减去便是答案。
完整代码如下:
#include<iostream>
#include<cstring>
const int M=105;
int a[M],dpl[M],dpr[M];
using namespace std;
int main(){
int N,i,n;
int lin1,lin2;
cin>>N;
for(i=0;i<N;i++)cin>>a[i];
dpl[0]=1; for(i=1;i<N;i++){ int max=0,w; for(w=0;w<i;w++){ if(a[w]<a[i]&&dpl[w]>max)max=dpl[w]; } dpl[i]=max+1; }
dpr[N-1]=1; for(i=N-2;i>=0;i--){ int max=0,w; for(w=i+1;w<N;w++){ if(a[i]>a[w]&&dpr[w]>max)max=dpr[w]; } dpr[i]=max+1; }
int max=-1,sum;
for(i=0;i<N;i++){
sum=dpl[i]+dpr[i];
if(sum>max)max=sum;
}
max-=1;
printf("%d",N-max);
return 0;
}
//大一菜鸟,有错误欢迎评论ヾ(๑╹◡╹)ノ"ヾ(๑╹◡╹)ノ"
相关文章推荐
- 【模板】LIS模板 洛谷P1091 [NOIP2004提高组]合唱队形 [2017年4月计划 动态规划11]
- [NOIP2004] 提高组 洛谷P1091 合唱队形
- 【NOIP·TG2004】caioj1065·动态规划入门(一维一边推3:合唱队形)
- [NOIP2004]合唱队形【动态规划】
- [NOIP提高组2004]合唱队形
- [DP][NOIP2004] 合唱队形
- 洛谷P1091 合唱队形
- 洛谷 P1091 合唱队形
- 洛谷 P1091 合唱队形
- 【原题】【noip 2004 T3】【动态规划】合唱队型
- 洛谷 P1091 合唱队形
- noip2004合唱队形2008.11.4
- NOIP 2004 提高组 复赛 chorus 合唱队形
- noip2004 合唱队形 (最长严格上升子序列+最长严格下降子序列)
- NOIP2004 合唱队形
- ACM 109. [NOIP2004] 合唱队形(dp+枚举)
- 【NOIP2004】合唱队形
- noip 2004-合唱队形-dp
- 【最长上升子序列】[NOIP2004提高组]合唱队形
- 【DP】洛谷 P1091 合唱队形