[noip2013 d2t2]花匠

题意:给定一串数,求最多可留下多少个呈波浪状排列的数

对于30%:最最朴素的暴力

对于70%:考虑O(n2) dp

设f[i][1]为以第i个数为结尾的序列,满足条件A的最优解;f[i][2]为以第i个数为结尾的序列,满足条件B的最优解

题目给出的两个条件,其实为状态转移提供了思路

不难得出方程

f[i][1]=max(f[j][2]+1)(j<i,h[i]>h[j])

f[i][2]=max(f[j][1]+1)(j<i,h[i]<h[j])

初始f[i][1]=f[i][2]=1;

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<ctype.h>
 5 using namespace std;
 6 const int maxn=100100;
 7 int f[maxn][3],h[maxn];
 8 int read(){
 9     int x=0;
10     char ch=getchar();
11     while (!isdigit(ch)) ch=getchar();
12     while (isdigit(ch)){
13         x=x*10+ch-‘0‘;
14         ch=getchar();
15     }
16     return x;
17 }
18 int main(){
19     int n=read();
20     for (int i=1;i<=n;i++){
21         h[i]=read();
22         f[i][1]=f[i][2]=1;
23     }
24     int ans=1;
25     for (int i=1;i<=n;i++){
26         for (int j=1;j<i;j++){
27             if (h[i]>h[j]) f[i][1]=max(f[i][1],f[j][2]+1);
28             if (h[i]<h[j]) f[i][2]=max(f[i][2],f[j][1]+1);
29         }
30         ans=max(ans,max(f[i][1],f[i][2]));
31     }
32     printf("%d\n",ans);
33     return 0;
34 }

然而这并不足以通过所有测试,n=10w的规模让我们考虑优化

观察可知 f数组是单调递增的,所以我们可以倒序查找,找到上一个有解的f就退出

亦可修改方程,每个点都保存此前的最优值,令i只和i-1有关

两种方法的时间均可视为O(n)级别,前者常数稍大些

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<ctype.h>
 5 using namespace std;
 6 const int maxn=100100;
 7 int f[maxn][3],h[maxn];
 8 int read(){
 9     int x=0;
10     char ch=getchar();
11     while (!isdigit(ch)) ch=getchar();
12     while (isdigit(ch)){
13         x=x*10+ch-‘0‘;
14         ch=getchar();
15     }
16     return x;
17 }
18 int main(){
19     int n=read();
20     for (int i=1;i<=n;i++){
21         h[i]=read();
22         f[i][1]=f[i][2]=1;
23     }
24     int ans=1;
25     for (int i=1;i<=n;i++){
26         for (int j=i-1;j>0;j--){
27             if (h[i]>h[j]) f[i][1]=max(f[i][1],f[j][2]+1);
28             if (h[i]<h[j]) f[i][2]=max(f[i][2],f[j][1]+1);
29             if (f[i][1]!=1&&f[i][2]!=1) break;
30         }
31     }
32     printf("%d\n",max(f[n][1],f[n][2]));
33     return 0;
34 }

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<ctype.h>
 5 using namespace std;
 6 const int maxn=100100;
 7 int f[maxn][3],h[maxn];
 8 int read(){
 9     int x=0;
10     char ch=getchar();
11     while (!isdigit(ch)) ch=getchar();
12     while (isdigit(ch)){
13         x=x*10+ch-‘0‘;
14         ch=getchar();
15     }
16     return x;
17 }
18 int main(){
19     int n=read();
20     for (int i=1;i<=n;i++){
21         h[i]=read();
22         f[i][1]=f[i][2]=1;
23     }
24     for (int i=2;i<=n;i++){
25         if (h[i]==h[i-1]) {
26             f[i][1]=f[i-1][1];
27             f[i][2]=f[i-1][2];
28         }
29         if (h[i]>h[i-1]){
30             f[i][1]=max(f[i-1][2]+1,f[i][1]);
31             f[i][2]=f[i-1][2];
32         }
33         if (h[i]<h[i-1]){
34             f[i][1]=f[i-1][1];
35             f[i][2]=max(f[i-1][1]+1,f[i][2]);
36         }
37     }
38     printf("%d\n",max(f[n][1],f[n][2]));
39     return 0;
40 }

还有一种更简洁的方法:对于一个单调序列中的所有点,可以缩为一个点,故只需统计原序列的拐点个数即可,也是O(n)

时间: 2024-11-03 22:32:42

[noip2013 d2t2]花匠的相关文章

洛谷 P1570【NOIP2013】花匠

题目描述 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大,也越来越挤.栋栋决定 把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空间长大,同时,栋栋希 望剩下的花排列得比较别致. 具体而言,栋栋的花的高度可以看成一列整数h1,h2..hn.设当一部分花被移走后,剩下的花的高度依次为g1,g2..gn,则栋栋希望下面两个条件中至少有一个满足: 条件 A:对于所有g(2i)>g(2i-1),g(2i)>g(2i+1) 条件 B:对于所有g(2i)<g(2i-1),g(2i)

【NOIP2013】花匠

Description 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大,也越来越挤.栋栋决定把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空间长大,同时,栋栋希望剩下的花排列得比较别致. 具体而言,栋栋的花的高度可以看成一列整数h1, h2, - , hn.设当一部分花被移走后,剩下的花的高度依次为g1, g2, - , gm,则栋栋希望下面两个条件中至少有一个满足: 条件 A:对于所有的1 ≤ i < m / 2,g_2i > g_2i?1,且g_2i > g_2i

NOIp2013 T5 花匠

[NOIP2013T5]花匠 Time Limit: 1000ms    Memory Limit: 131072KB 描述Descript. 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大,也越来越挤.栋栋决定把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空间长大,同时,栋栋希望剩下的花排列得比较别致. 具体而言,栋栋的花的高度可以看成一列整数?1, ?2, … , ?n.设当一部分花被移走后,剩下的花的高度依次为g1, g2, … , gm,则栋栋希望下面两个条件中至少有

&lt;NOIP2013 花匠&gt; 新人解题报告

本来按照老师的要求,我学OI的第一份解题报告应是在寒假完成的关于数据结构的基础题,但由于身体原因当时未能完成,那么就在省选赛前临时写几篇吧-- 题目描述 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大,也越来越挤.栋栋决定把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空间长大,同时,栋栋希望剩下的花排列得比较别致. 具体而言,栋栋的花的高度可以看成一列整数?1, ?2, - , ?n.设当一部分花被移走后,剩下的花的高度依次为g1, g2, - , gm,则栋栋希望下面两个条

洛谷 P1970 花匠(NOIp2013提高组D2T2)

题目描述 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大,也越来越挤.栋栋决定 把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空间长大,同时,栋栋希 望剩下的花排列得比较别致. 具体而言,栋栋的花的高度可以看成一列整数h1,h2..hn.设当一部分花被移走后,剩下的花的高度依次为g1,g2..gn,则栋栋希望下面两个条件中至少有一个满足: 条件 A:对于所有g(2i)>g(2i-1),g(2i)>g(2i+1) 条件 B:对于所有g(2i)<g(2i-1),g(2i)

[NOIP2013] 提高组 洛谷P1970 花匠

题目描述 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大,也越来越挤.栋栋决定 把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空间长大,同时,栋栋希 望剩下的花排列得比较别致. 具体而言,栋栋的花的高度可以看成一列整数h1,h2..hn.设当一部分花被移走后,剩下的花的高度依次为g1,g2..gn,则栋栋希望下面两个条件中至少有一个满足: 条件 A:对于所有g(2i)>g(2i-1),g(2i)>g(2i+1) 条件 B:对于所有g(2i)<g(2i-1),g(2i)

NOIP2013花匠

描述 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大,也越来越挤.栋栋决定把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空间长大,同时,栋栋希望剩下的花排列得比较别致. 具体而言,栋栋的花的高度可以看成一列整数h1, h2, … , hn.设当一部分花被移走后,剩下的花的高度依次为g1, g2, … , gm,则栋栋希望下面两个条件中至少有一个满足: 条件 A:对于所有的1<i<m/21im2,g2i>g2i−1g2ig2i1,且g2i>g2i+1g2ig2i1

洛谷P1970 [NOIP2013提高组Day2T2] 花匠

P1970 花匠 题目描述 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大,也越来越挤.栋栋决定 把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空间长大,同时,栋栋希 望剩下的花排列得比较别致. 具体而言,栋栋的花的高度可以看成一列整数h1,h2..hn.设当一部分花被移走后,剩下的花的高度依次为g1,g2..gn,则栋栋希望下面两个条件中至少有一个满足: 条件 A:对于所有g(2i)>g(2i-1),g(2i)>g(2i+1) 条件 B:对于所有g(2i)<g(2i

刷过一题之NOIP2013花匠

花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大,也越来越挤.栋栋决定把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空间长大,同时,栋栋希望剩下的花排列得比较别致.具体而言,栋栋的花的高度可以看成一列整数h1,h2, … ,hn.设当一部分花被移走后,剩下的花的高度依次为g1,g2, … ,gm,则栋栋希望下面两个条件中至少有一个满足:       注意上面两个条件在m=1时同时满足,当m>1时最多有一个能满足.请问,栋栋最多能将多少株花留在原地. 输入: 第二行包含n个整数,