P1970 花匠
直接粘题解+代码。
这个题解比其他的DP不知道高到哪里去了,吼哇!
/// //////////
【背景】 作为往年的noip题,我曾经当作dp题写过,时间比较吃紧。
但是我最近做的一套模拟题里有这道题的强化(数据强化为10000000,时间变为2秒),所以不得不思考贪心做法(要用读入优化)。
【解法】 贪心做法其实不是太难想。这道题其实就是找到一个最长的波浪序列(每一盆花都是波峰或波谷)。
首先,对于第一盆花,不论如何都要选,因为如果不选,第二盆花就相当于第一盆,而花的总数却减少了,所以一定不会更优。
对于第二盆花,如果和第一盆等高,就没有用,可以直接不选(这时候还是找第二盆);如果比第一盆高,那么它就一定要作为波峰(如果作为波谷则等同于第一盆没选);同理如果比第一盆低就一定是波谷。
对于后面的花,如果找波峰,如果当前花比上一盆高,那么波峰就找到了,接下来找波谷;如果不如上一盆高,那么用这盆更低的花继续找波峰结果一定不会更差。找波谷同理。
在操作过程中记录留下多少花即可。
结合代码思考一下。
【代码】(看不懂可以私信我)
1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 bool flag1,flag2;//flag1:是否找到第二盆花;flag2:当前找波峰还是波谷,1:找波峰; 0:找波谷 5 int n,lst,h,ans;//h:当前花高度;lst:上一盆花高度;ans:答案 6 inline int red() 7 { 8 int X=0,w=1; 9 char ch=0; 10 while(ch<'0'||ch>'9') 11 { 12 if(ch=='-') 13 { 14 w=-1; 15 } 16 ch=getchar(); 17 } 18 while(ch<='9'&&ch>='0') 19 { 20 X=(X<<3)+(X<<1)+ch-'0'; 21 ch=getchar(); 22 } 23 return X*w; 24 } 25 int main() 26 { 27 // freopen("flower.in","r",stdin);freopen("flower.out","w",stdout); 28 n=red(); 29 int i=0; 30 for(i=1;i<=n;i++) 31 { 32 h=red(); 33 if(i==1) 34 { 35 lst=h; 36 ans++; 37 } 38 else if(!flag1)//如果没找到第二盆花 39 { 40 if(h>lst) 41 { 42 ans++; 43 flag1=1;//表示已经找到第二盆花 44 lst=h; 45 } 46 else if(h<lst) 47 { 48 ans++; 49 flag1=1;//表示已经找到第二盆花 50 flag2=1; 51 lst=h; 52 } 53 } 54 else 55 { 56 if(flag2==0) 57 { 58 if(h<lst) 59 { 60 ans++; 61 flag2=1;//已找到波谷,接下来找波峰 62 } 63 lst=h; 64 } 65 else 66 { 67 if(h>lst) 68 { 69 ans++; 70 flag2=0;//已找到波峰,接下来找波古 71 } 72 lst=h; 73 } 74 } 75 } 76 printf("%d\n",ans); 77 return 0; 78 }
/// ////////
我的代码:
1 #include <cstdio>
2 using namespace std;
3
4 int h[100004],last;
5 int n,ans=2;
6 bool flag;///false找大,true找小
7
8 int main()
9 {
10 scanf ("%d",&n);
11 scanf ("%d",&h[1]);
12 int i=2;
13 while(!last)
14 {
15 scanf ("%d",&h[i]);
16 if(h[i]==h[1])
17 {
18 i++;
19 continue;
20 }
21 if(h[i]>h[1]) flag=1;
22 last=h[i];
23 i++;
24 }
25 for(;i<=n;i++)
26 {
27 scanf ("%d",&h[i]);
28
29
30
31 if(h[i]==last) continue;
32 else if(h[i]>last)
33 {
34 if(!flag)
35 {
36 ans++;
37 flag=1;
38 }
39 last=h[i];
40 }
41 else
42 {
43 if(flag)
44 {
45 ans++;
46 flag=0;
47 }
48 last=h[i];
49 }
50
51
52 /*
53 if(flag)
54 {
55 if(h[i]<last)
56 {
57 flag=0;
58 ans++;
59 }
60 last=h[i];
61 }
62 else
63 {
64 if(h[i]>last)
65 {
66 flag=1;
67 ans++;
68 }
69 last=h[i];
70 }
71
72 */
73
74 }
75 printf("%d",ans);
76 return 0;
77 }