C. Playing Piano 動態規劃
阿新 • • 發佈:2018-11-22
題目意思是給你一個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();
}
}