Codeforces 1079C Playing Piano(记忆化搜索)
题目链接:Playing Piano
题意:给定长度为n的序列$a_i$,要求得到同样长度的序列$b_i$。满足一下条件:
if $a_i < a_{i+1}$ then $b_i < b_{i+1}$
if $a_i > a_{i+1}$ then $b_i > b_{i+1}$
if $a_i = a_{i+1}$ then $b_i \neq\ b_{i+1}$
$1 <= b_i <= 5$
题解:第一个数从1-5枚举,接着从下一位开始搜索,dp[i][j]表示第i位数字为j的情况是否已经搜索过。
当$a_i<a_{i+1}$的时候,从当前值往后搜索;当$a_i>a_{i+1}$的时候,从当前值往前搜索;$a_i=a_{i+1}$的时候,搜索和当前值不相同的值。搜索的区间范围为1-5。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstdlib> 3 using namespace std; 4 5 const int N=1e5+10; 6 int n,a[N],b[N],dp[N][10]; 7 8 void dfs(int x,int val){ 9 if(x>n){ 10 printf("%d",b[1]); 11 for(int i=2;i<=n;i++) printf(" %d",b[i]); 12 printf("\n"); 13 exit(0); 14 } 15 if(dp[x][val]) return ; 16 dp[x][val]=1; 17 if(a[x]>a[x-1]){ 18 for(int i=val+1;i<=5;i++){ 19 b[x]=i; 20 dfs(x+1,i); 21 } 22 } 23 else if(a[x]<a[x-1]){ 24 for(int i=1;i<=val-1;i++){ 25 b[x]=i; 26 dfs(x+1,i); 27 } 28 } 29 else{ 30 for(int i=1;i<=5;i++){ 31 if(i!=val){ 32 b[x]=i; 33 dfs(x+1,i); 34 } 35 } 36 } 37 } 38 39 int main(){ 40 scanf("%d",&n); 41 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 42 for(int i=1;i<=5;i++){ 43 b[1]=i; 44 dfs(2,i); 45 } 46 printf("-1\n"); 47 return 0; 48 }