1. 程式人生 > >C. Playing Piano 動態規劃

C. Playing Piano 動態規劃

題目意思是給你一個n長度的數字串為a,讓你構造一個n長度的數字串b值都為1-5滿足以下條件:

 

正常的dfs暴力構造會超時,我試過了。。

可以開一個二維陣列dp[i][j]用來表示b的第i個數字為j是否可行,標記為1或0;

因為第i個數字的大小隻會影響第i+1個數字,每次確定i都根據第i-1的數字來判斷。

再開一個二維陣列pre[i][j]用來表示b的第i個 數字為j時的前一個數字是多少,最後倒推時用stack記錄一下輸出答案;

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10
; int a[maxn]; int dp[maxn][6]; int pre[maxn][6]; stack<int> s; int main() { int n; scanf("%d", &n); for(int i=1; i<=n; i++) scanf("%d", &a[i]); for(int i=1; i<=5; i++) dp[1][i]=1; for(int i=2; i<=n; i++) for(int j=1; j<=5; j++) {
if(dp[i-1][j]==0) continue; if(a[i]>a[i-1]) { for(int k=j+1; k<=5; k++) { dp[i][k]=1; pre[i][k]=j; } } if(a[i]<a[i-1]) {
for(int k=j-1; k>=1; k--) { dp[i][k]=1; pre[i][k]=j; } } if(a[i]==a[i-1]) { for(int k=1; k<=5; k++) if(k!=j) { dp[i][k]=1; pre[i][k]=j; } } } for(int i=1; i<=n; i++) { for(int j=1; j<=5; j++) printf("%d ", pre[i][j]); printf("\n"); } int t=0; for(int j=1; j<=5; j++) { if(dp[n][j]==1) t=j; } if(t==0) { printf("-1");return 0; } for(int i=n; i>=1; i--) { s.push(t); t=pre[i][t]; } while(!s.empty()) { printf("%d ", s.top()); s.pop(); } }