华师一附中OI组
标题:
P1970 花匠
[打印本页]
作者:
YTC
时间:
2018-6-5 17:10
标题:
P1970 花匠
https://www.luogu.org/problemnew/show/P1970
题目描述
花匠栋栋种了一排花,每株花都有自己的高度。花儿越长越大,也越来越挤。栋栋决定把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空间长大,同时,栋栋希望剩下的花排列得比较别致。
具体而言,栋栋的花的高度可以看成一列整数 h_1,h_2,...,h_n。设当一部分花被移走后,剩下的花的高度依次为 g_1,g_2,...,g_m ,则栋栋希望下面两个条件中至少有一个满足:
条件 A:对于所有 g_2i>g_2i-1,g_2i>g_2i+1
条件 B :对于所有 g_2i<g_2i-1,g_2i<g_2i+1
注意上面两个条件在 m=1时同时满足,当 m > 1时最多有一个能满足。
请问,栋栋最多能将多少株花留在原地。
输入输出格式
输入格式:
第一行包含一个整数 n ,表示开始时花的株数。
第二行包含 n 个整数,依次为 h_1,h_2,...,h_n ,表示每株花的高度。
输出格式:
一个整数 m ,表示最多能留在原地的花的株数。
输入输出样例
输入样例#1:
5
5 3 2 1 2
输出样例#1:
3
作者:
胡雨菲菲
时间:
2018-6-5 18:02
#include <cstdio>
using namespace std;
int h[100004],last;
int n,ans=2;
bool flag;///false找大,true找小
int main()
{
scanf ("%d",&n);
scanf ("%d",&h[1]);
int i=2;
while(!last)
{
scanf ("%d",&h[i]);
if(h[i]==h[1])
{
i++;
continue;
}
if(h[i]>h[1]) flag=1;
last=h[i];
i++;
}
for(;i<=n;i++)
{
scanf ("%d",&h[i]);
if(h[i]==last) continue;
else if(h[i]>last)
{
if(!flag)
{
ans++;
flag=1;
}
last=h[i];
}
else
{
if(flag)
{
ans++;
flag=0;
}
last=h[i];
}
/*
if(flag)
{
if(h[i]<last)
{
flag=0;
ans++;
}
last=h[i];
}
else
{
if(h[i]>last)
{
flag=1;
ans++;
}
last=h[i];
}
*/
}
printf("%d",ans);
return 0;
}
复制代码
作者:
YTC
时间:
2018-6-13 13:03
法一:DP
用两个数组分别记录到i下降和到i上升
#include<bits/stdc++.h>
using namespace std;
const int N=100010
int a[N],f[N][2];
int n,tmp=0;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
f[1][0]=f[1][1]=1;
for(int i=2;i<=n;i++){
if(a[i]>a[i-1])f[i][0]=f[i-1][1]+1;
else f[i][0]=f[i-1][0];
if(a[i]<a[i-1])f[i][1]=f[i-1][0]+1;
else f[i][1]=f[i-1][1];
}
cout<<max(f[n][0],f[n][1]);
return 0;
}
复制代码
作者:
YTC
时间:
2018-6-13 13:09
法二:贪心
复制一波洛谷的题解
/*这道题其实就是找到一个最长的波浪序列(每一盆花都是波峰或波谷)。
首先,对于第一盆花,不论如何都要选,因为如果不选,第二盆花就相当于第一盆,而花的总数却减少了,所以一定不会更优。
对于第二盆花,如果和第一盆等高,就没有用,可以直接不选(这时候还是找第二盆);如果比第一盆高,那么它就一定要作为波峰(如果作为波谷则等同于第一盆没选);同理如果比第一盆低就一定是波谷。
对于后面的花,如果找波峰,如果当前花比上一盆高,那么波峰就找到了,接下来找波谷;如果不如上一盆高,那么用这盆更低的花继续找波峰结果一定不会更差。找波谷同理。
在操作过程中记录留下多少花即可。
*/
楼上dalao就是这样写的
下面是本蒟蒻的代码
#include<iostream>
using namespace std;
int a[100005];
int n,p;
int ans1,ans2;
int now;
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
p=0;
now=a[1];
ans1=1;
for(int i=2;i<=n;i++)
{
if(p==0)
if(now>a[i])
{
ans1++;
now=a[i];
p=1;
}
else now=a[i];
if(p==1)
if(now<a[i])
{
ans1++;
now=a[i];
p=0;
}
else now=a[i];
}
p=1;
now=a[1];
ans2=1;
for(int i=2;i<=n;i++)
{
if(p==0)
if(now>a[i])
{
ans2++;
now=a[i];
p=1;
}
else now=a[i];
if(p==1)
if(now<a[i])
{
ans2++;
now=a[i];
p=0;
}
else now=a[i];
}
cout<<max(ans1,ans2);
return 0;
}
复制代码
作者:
YTC
时间:
2018-6-13 13:14
对贪心思路进行分析,可知只需找波峰和波谷即可
下面是洛谷题解的代码
#include<bits/stdc++.h>
using namespace std;
int n,h[1000005],ans=1;bool con;
int main()
{
cin>>n;for(int i=1;i<=n;i++) cin>>h[i];
if(h[2]>=h[1]) con=1;
for(int i=1;i<=n;i++)
{
if(con==0&&i==n) {ans++;break;}
if(con==1) if(h[i+1]<h[i]){ans++;con=0;continue;}
if(con==0) if(h[i+1]>h[i]) {ans++;con=1;continue;}
}
cout<<ans;
}
复制代码
注意特判第二朵来贪心,最后一朵一定保留
作者:
吴语林
时间:
2018-7-30 00:06
#include <algorithm>
#include <iostream>
#include <cmath>
#include <cstring>
#include <map>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <cstdio>
#include <cstdlib>
using namespace std;
int n,j,all=0,l,x,e=1;
int main()
{
scanf("%d%d",&n,&l);n--;
while(e)
{
scanf("%d",&x);
n--;
if(l<x)
j=1,all=2,l=x,e=0;
else if(l>x)
j=0,all=2,l=x,e=0;
}
while(n--)
{
scanf("%d",&x);
if(j==1)
{
if(l>x)
j=0,all++;
l=x;
}
else
{
if(l<x)
j=1,all++;
l=x;
}
}
printf("%d",all);
return 0;
}
复制代码
作者:
universehyf
时间:
2018-9-25 20:34
#include<iostream>
using namespace std;
#define FOR(iii,nn,mm) for(int iii=nn;iii<=mm;iii++)
long long h[100010];
long long n,c,ans=2,t;
int main()
{
cin>>n>>h[0];FOR(i,1,n-1) {cin>>t;if(t!=h[c]) h[++c]=t;}
FOR(i,1,c-1) if((h[i]-h[i-1])*(h[i]-h[i+1])>0) ans++;
c==0?cout<<1:cout<<ans;
return 0;
}
复制代码
作者:
admin
时间:
2018-9-26 16:57
楼上HYF的程序好牛呀 短小精悍
作者:
universehyf
时间:
2018-9-26 19:49
本帖最后由 universehyf 于 2018-9-26 19:51 编辑
这是我看了蒋轩林的程序写的代码
欢迎光临 华师一附中OI组 (http://hsyit.cn/)
Powered by Discuz! X3.2