Codeforces Round #522(Div. 2) C.Playing Piano
题意: 给出一个数列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 }
贪心思路:
如果 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[ ] 从前往后 每个位置都遍历
。