ACM第四五周总结
第一周初识动态规划:
动态规划即求每一阶段最优解以达到总体最优。起初以为是每一阶段求最优然后累加即可。但实际并不是,若只是每一阶段累加,则会忽略其他情况,从而缺少对最优解的讨论。所以动态求最优,还是实现了对所有可能的讨论,以求出最优。例如吃金币问题如果只是从第一步开始对每一步都求最大然后累加,最后的结果并不一定最大。如果用动态转移方程
F[a][b]=max(F[a-1][b],F[a][b-1])+c
则实现了对各种情况的讨论,以每一阶段最优达到全体最优刚刚学习时,遇到类似问题,几乎没有想法,最多只有用暴力解题。但大多情况暴力解题不仅代码编写复杂,而且容易出现超时等情况。例如vj第一题,通过分析明白给出的数据其实符合一定规律,即+波峰-波谷。通过这样的规律,只需要将所有的波峰波谷按顺序求出并储存,最后先加后减,达到最大即可。这样的问题就不需要用到状态转移。而若用状态转移则代码简单且优化
dp[i][0] = max(dp[i-1][0], dp[i-1][1]- v[i]);
dp[i][1] =max(dp[i-1][1], dp[i-1][0]+v[i]);
用0,1表示位置,i表示用药次数。
第二周做题体会:
一周之内并没有做出太多的题,归结原因还是对动态规划的理解不到。每次对各个阶段分析,总是考虑到计算每一种情况,这样一想,思路就偏向贪心,思路就更加复杂,但实际的状态转移方程仅仅只有几行。如何做出正确的状态转移方程才是关键。动态规划的思路才是解题关键。这一周做了最大连续子列问题(P T )只需要考虑累加时比前面阶段更大即可保证当前项和前面的累加值dp和可以更大所以构建
dp[i]=max(dp[i-1]+a[i],0)
之后类似题目还有B题求公共子序列
for(i=0;i<b.size();i++)
for(j=0;j<a.size();j++){if(a[j]==b[i])c[i+1][j+1]=c[i][j]+1;
else c[i+1][j+1]=max(c[i][j+1],c[i+1][j]);}
总结:动态规划问题思路仍是很大问题,这一周的学习没能理解,做题速度很慢,个人的冥思苦想不能带来太大作用(不能理解),多看题解掌握方法还是很重要的,总之一周的学习并不理想,任重而道远。
end