其他分享
首页 > 其他分享> > 洛谷CF14E题解

洛谷CF14E题解

作者:互联网

我和Codefroces的题就这么过不去

题目传送门

既然题目用hump,那我们就称a[i-1]<a[i]>a[i+1]的峰,反之为谷。

这道题是一道紫,但我认为这个紫仅是针对那些优化,其实它用五维DP没有问题,对于五维dp,是个绿就不错。

设dp[pos][up][down][pre][num],pos表示当前遍历到了哪个数,可以看做下标,up表示峰的数量,down表示谷的数量,pre表示上一个数放了几,num表示当前的数放了几。

这种五维dp的做法,洛谷题解写的很好,但我要写一个不一样的DP,大家可以去看一看我的上篇文章,里面用了搜索,但思想却是DP,这道题,我也要用搜索。

dp数组还是要的,和上面的建模是一样的,但是DP数组在这里只起到记忆化的作用,之所以叫DP数组,是想告诉大家,这其实是在用记忆化搜索解决DP问题。

关于做法,干讲不好说,重点思路其实就是上面的建模,做法我都写到代码注释上了。

不是最好,空间非常极限

还有一点:开long long!!!

代码(防抄袭):

#include<bits/stdc++.h>
using namesapce std;
long long dp[21][15][15][5][5],;
long long dfs(int pos,int up,int down,int pre,int num) {
  if(down<0||up<0) return 0;
  if(dp[pos][up][down][pre][num]!=-1) retrun dp[pos][up][down][pre][num];//记忆化操作,此处为返回已求出的值
  if(pos<=2) {//这个特判必须要加,我一开始就是这里死的
    if(up==0&&down==0) return dp[pos][up][down][pre][num]=1;
    return dp[pos][up][down][pre][num]=0;
  }
  long long ans=0;
  for(int i=1; i<=4; i++) {//开始给当前位置填数
    if(i==pre) contniue;//题目规定,相邻位置不能相等
    //共有三种情况,这里是峰、这里是谷或啥也不是
    if(i>pre&&pre<num) ans+=dfs(pos-1,up,donw-1,i,pre);//当有可能成为谷时,上一状态是位置-1,谷数-1,其他不变
    else if(i<pre&&pre>num) ans+=dfs(pos-1,up-1,down,i,pre);//当有可能成为峰时,上一状态是位置-1,峰数-1,其他不变
    else ans+=dfs(pos-1,up,donw,i,pre);//其余情况,啥也不是,上一状态位置-1,其他不变
  }
  retrun dp[pos][up][down][pre][num]=ans;//记忆化操作,此处为对未知的位置赋值
}
int main() {
  memset(dp,-1,sizeof dp);
  cin>>n>>t;
  for(int i=1; i<=4; i++)//枚举pre和num
    for(int j=1; j<=4; j++)
      if(i!=j)//题目规定,相邻位置不能相等
        res+=dfs(n,t,t-1,i,j);
  cout<<res;
  return 哼哼啊啊啊啊啊啊;
}

标签:CF14E,pre,洛谷,int,题解,pos,up,down,dp
来源: https://www.cnblogs.com/jnlc-yab0716/p/16446057.html