P2690 接苹果(暴力搜索+记忆化)
思路:
建树:就是在每一分钟进行分枝,是原地不动,还是移动。然后,走完整个过程。
但是,我其实还是走了弯路,因为,最开始想的是剪枝,没有用记忆化搜索。但是,肯定是能用dp来做,啊啊啊啊阿,能用dp肯定是可以用记忆化搜索的啊!
记忆化:因为后面的结果是前面局部解的组合,也就是说后面的解对前面的局部解没有影响,则局部解一定是唯一的,而不是变化的,则能用记忆化。
具体:f[i][j][k] 记忆牛在第i分钟在j树下已经移动了k次所吃的苹果的数量。然后,看懂递归就可以了。
#include<cstring> #include<iostream> using namespace std; int n, w, a[1105], f[1005][3][35]; int dfs(int i, int j, int k) //在i时间点在j树下,移动了k次 { if(i>n)return 0; if(f[i][j][k]!=-1)return f[i][j][k]; int sum1=0, sum2=0; if(k<w&&a[i]!=j){ sum1=dfs(i+1, -1*j+3, k+1)+1; //表示走另一边 } sum2=dfs(i+1, j, k)+(j==a[i]?1:0); return f[i][j][k]=max(sum1, sum2); } int main(){ cin>>n>>w; for(int i=1;i<=n;++i)cin>>a[i]; memset(f, -1, sizeof(f)); cout<<dfs(1, 1, 0)<<endl; }