Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3) C
阿新 • • 發佈:2019-02-03
題意:給你一個長度為n的序列a,根據序列a,按照如下要求構造序列b:
1:若a【i】 > a【i+1】 則,b【i】 > b【i+1】
1:若a【i】 < a【i+1】 則,b【i】 < b【i+1】
1:若a【i】 = a【i+1】 則,b【i】 != b【i+1】
b【i】取值範圍為【1,5】,n的範圍為2e5.
輸出序列b。若構造不出來輸出-1
題解:因為需要列印路徑,所以定義dp【i】【j】表示b序列中第 i 位置為 j 的上一個位置是幾。然後從n位置遞迴找出一條可行的序列。
程式碼如下:
#include<bits/stdc++.h> using namespace std; const int maxn = 2e5 +10; int A[maxn]; int dp[maxn][10]; int main(){ int n; cin >> n; for(int i = 1 ; i <= n ; i ++) cin >> A[i]; memset(dp,-1,sizeof(dp)); for(int i = 1 ; i <= 5 ; i ++){ // 初始化 dp[1][i] = i; } for(int i = 2 ; i <= n ; i ++){ for(int j = 1 ; j <= 5 ; j ++){ if(A[i] > A[i-1]){ for(int k = 1 ; k < j ; k ++){ if(dp[i-1][k] >= 0){ dp[i][j] = k; } } } else if(A[i] < A[i-1]){ for(int k = j + 1; k <= 5 ; k ++){ if(dp[i-1][k] >= 0) dp[i][j] = k; } } else { for(int k = 1 ; k <= 5 ; k ++){ if(k != j && dp[i-1][k] >= 0) dp[i][j] = k; } } } } int start = -1; stack<int> s; for(int j = 1 ; j <= 5 ; j ++){ if(dp[n][j] >= 0){ s.push(j); start = j; break; } } if(start == -1){ cout << -1; return 0; } for(int i = n ; i >= 2 ; i --){ s.push(dp[i][start]); start = dp[i][start]; } while(!s.empty()){ cout << s.top() << " "; s.pop(); } return 0; }