该题第一思路是使用搜索枚举所有可能的情况,最后取最大值即可
#include<iostream> #include<climits> #include<algorithm> using namespace std; int t,w; int arr[1010]; int ans=INT_MIN; void dfs(int cur,int i,int w,int apples){//cur当前奶牛处在哪棵树下,i当前时刻,w所剩移动次数 if(i==t+1){//终点 // cout<<apples<<endl; ans=max(ans,apples); }else{ int temp=(cur==arr[i]);//能否接到 dfs(cur,i+1,w,apples+temp);//不动 if(w!=0){ int to=1; if(cur==1){ to=2; temp=(to==arr[i]);//换位后能否接到 dfs(2,i+1,w-1,apples+temp); }else if(cur==2){ to=1; temp=(to==arr[i]); dfs(1,i+1,w-1,apples+temp); } } } } int main(){ cin>>t>>w; for(int i=1;i<=t;i++){ cin>>arr[i]; } dfs(1,1,w,0); cout<<ans<<endl; return 0; }
但是由于该题数据量的限制,并不能通过所有样例
因此我们考虑使用记忆化搜索进行优化
即使用一个记忆数组来存储某种情况下奶牛能得到的最大苹果数
#include<iostream> #include<algorithm> #include<cstring> using namespace std; int t,w; int arr[1010]; int s[1010][3][40]; int dfs(int i,int j,int w){//i为当前时间点,j为所处树,w为所剩移动次数 if(i>t){ return 0; } if(s[i][j][w]!=-1){ return s[i][j][w];//记忆 } int des1=0,des2=0;//两种决策 if(w>0){//还有移动次数 int to=3+(-1)*j; des1=dfs(i+1,to,w-1)+(arr[i]==to);//如果3+(-1)*j表示当前在1就移动到2,当前在2就移动到1 } des2=dfs(i+1,j,w)+(arr[i]==j); return s[i][j][w]=max(des1,des2);//取最好决策 } int main(){ cin>>t>>w; for(int i=1;i<=t;i++){ cin>>arr[i]; } memset(s,-1,sizeof(s)); cout<<dfs(1,1,w)<<endl; return 0; }