首先来个爆搜再说。
定义 dfs(int i,int pre,int ans)
表示当前是 \(i\) 时间,上一次在 \(\rm pre\) 苹果树,已经移动 \(\rm ans\) 次的最大苹果数量。
如果 i>t
,返回 \(0\) 即可。
如果上一次苹果树的位置跟当前一样,就不用移动,返回dfs(i+1,a[i],ans)+1
。
如果上一次跟当前位置不一样,可以不移动也可以移动,如果移动次数小于 \(w\) ,就可以选择移动。
这样你可以获得 \(0\) 分的好成绩!
考虑记忆化,定义 \(dp_{i,ans}\) 表示第 \(i\) 时间移动 \(\rm ans\) 次的最大苹果数量。
每次搜索的时候过滤掉搜过的值就行了
代码:
#include<bits/stdc++.h>
using namespace std;
int t,w;
int a[1005];
int dp[1005][35];
int dfs(int i,int pre,int ans){//当前时间,上一次位置,次数
if(i>t) return dp[i][ans]=0;
if(pre==a[i]){
return dp[i][ans]=dfs(i+1,a[i],ans)+1;
}
else{
dp[i][ans]=dfs(i+1,pre,ans);
if(ans<w){
dp[i][ans]=max(dp[i][ans],dfs(i+1,a[i],ans+1)+1);
}
return dp[i][ans];
}
}
int main(){
memset(dp,-1,sizeof dp);
cin>>t>>w;
for(int i=1;i<=t;i++) cin>>a[i];
int d=dfs(1,1,0);//因为你不知道你上一次位置是哪里
memset(dp,-1,sizeof dp);
int w=dfs(1,0,0);
cout<<max(d,w)<<endl;
}