Codeforces Round #522(Div. 2) C.Playing Piano

题目

参考的题解:方法:   dp   贪心   dfs遍历 

题意: 给出一个数列a[n],让构造一个满足下列条件的数列b[n]:如果a[i]>a[i-1]那么b[i]>b[i-1],如果a[i]<a[i-1]那么b[i]<b[i-1],如果a[i]==a[i-1],那么b[i]!=b[i-1].

dp思路: 

用数组dp[i][k]表示 在要构造的数列中 第i个位置的值为k是否可行,可行的话dp[i][k]=1;  所有的dp[i][ ]都是从dp[i-1][ ] 获得。 用pre数组记录每个第i个位置上的值, 最终得出pre[n][ ] (这个表示第 n-1个位置的值是 pre[n][ ] )。  

 1 #include<iostream>
 2 #include<cstdio>
 3 #include <cctype>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cmath>
 7 #include<string>
 8 #include<cmath>
 9 #include<set>
10 #include<vector>
11 #include<stack>
12 #include<queue>
13 #include<map>
14 using namespace std;
15 #define ll long long
16 #define mem(a,x) memset(a,x,sizeof(a))
17 #define se second
18 #define fi first
19 const ll mod=1e9+7;
20 const int INF= 0x3f3f3f3f;
21 const int N=1e5+5;
22 
23 int n,a[N];
24 int dp[N][6];
25 int ans[N],pre[N][6];
26 
27 int main()
28 {
29     cin>>n;
30     for(int i=1;i<=n;i++)
31         scanf("%d",&a[i]);
32     
33     for(int i=1;i<=5;i++)
34         dp[1][i]=1;
35         
36     for(int i=1;i<n;i++)
37     {
38         for(int j=1;j<=5;j++)
39         {
40             if(dp[i][j]==0) continue;
41             
42             if( a[i] < a[i+1] )
43             {
44                 for(int k=j+1;k<=5;k++)
45                 {
46                     dp[i+1][k]=1;
47                     pre[i+1][k]=j;
48                 }
49             }
50             else if( a[i] > a[i+1] )
51             {
52                 for(int k=1;k<=j-1;k++)
53                 {
54                     dp[i+1][k]=1;
55                     pre[i+1][k]=j;
56                 }
57             }
58             else 
59             {
60                 for(int k=1;k<=5;k++)
61                 {
62                     if(j==k) continue;
63                     dp[i+1][k]=1;
64                     pre[i+1][k]=j;
65                 }
66             }
67         }
68     }
69     
70     int flag=0;
71     int u;
72     for(int i=1;i<=5;i++)
73     {
74         if(dp[n][i])
75         {
76             u=i;
77             for(int j=n;j>=1;j--)
78             {
79                 ans[j]=u;
80                 u=pre[j][u];
81             }
82             flag=1; break;
83         }
84     }
85     if(!flag)
86         cout<<-1<<endl;
87     else
88     {
89         for(int i=1;i<=n;i++)
90             cout<<ans[i]<<' ';
91     }
92 }
dp

贪心思路:

如果 a[i-1]==a[i] ,a[i]>a[i+1] ,则a[i] 在顶峰,若b[i-1]=5,则 b[i]=4; 若b[i-1]!=5, 则b[i]=5 

如果 a[i-1]==a[i] ,a[i]==a[i+1]  ,若b[i-1]=3,则 b[i]=2或4; 若b[i-1]!=3, 则b[i]=3

如果 a[i-1]==a[i] ,a[i]<a[i+1] ,则a[i] 在谷峰,若b[i-1]=1,则 b[i]=2; 若b[i-1]!=1, 则b[i]=1

对a[i-1]和a[i]的其他情况继续讨论  

 1 #include<iostream>
 2 #include<cstdio>
 3 #include <cctype>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cmath>
 7 #include<string>
 8 #include<cmath>
 9 #include<set>
10 #include<vector>
11 #include<stack>
12 #include<queue>
13 #include<map>
14 using namespace std;
15 #define ll long long
16 #define mem(a,x) memset(a,x,sizeof(a))
17 #define se second
18 #define fi first
19 const ll mod=1e9+7;
20 const int INF= 0x3f3f3f3f;
21 const int N=1e5+5;
22 
23 int n,a[N];
24 int b[N];
25 
26 int main()
27 {
28     cin>>n;
29     for(int i=1;i<=n;i++)
30         scanf("%d",&a[i]);
31     
32     if(a[2]>a[1])    b[1]=1;
33     else if(a[2]==a[1])     b[1]=3;
34     else    b[1]=5;
35     
36     for(int i=2;i<=n;i++)
37     {
38         if(a[i]==a[i-1])  
39         {
40             if(a[i+1]==a[i])
41                 b[i]= (b[i-1]==3)? 2: 3;
42             else if(a[i+1]>a[i])
43                 b[i]= (b[i-1]==1)? 2: 1;
44             else
45                 b[i]= (b[i-1]==5)? 4: 5;
46         }
47         
48         else if(a[i]>a[i-1])
49         {
50             if(a[i]>a[i+1] && b[i-1]!=5)
51                 b[i]=5;
52             else
53                 b[i]=b[i-1]+1;
54         }
55         
56         else if(a[i]<a[i-1])
57         {
58             if(a[i]<a[i+1]&& b[i-1]!=1)
59                 b[i]=1;
60             else
61                 b[i]=b[i-1]-1;
62         }
63         
64         if(b[i]<=0 || b[i]>=6){
65             cout<<-1<<endl;
66             return 0;
67         }
68     }
69     for(int i=1;i<=n;i++)
70         cout<<b[i]<<' ';
71 }
贪心

dfs思路: 对 b[ ] 从前往后 每个位置都遍历

原文地址:https://www.cnblogs.com/thunder-110/p/9995350.html