本周学习:区间dp,背包问题
感想:由于要军训,我就早写会博客,上一个线性dp的作业做的我感觉还可以,慢慢琢磨透了,每天写到晚上1点确实有点吃不消,我这周的做题就没那么久了,到晚上11点多就不学了,也就晚上能做一两个题,一开始能做两个,后面就能做一个了,因为区间dp的题有老师讲过的,我也就一下子就知道思路,没讲过的也就做的比较慢了,区间dp和线性dp不太一样,我觉得就是线性dp和区间dp中设的状态方程有所不同,表达的含义不同,区间dp就是把一行数分为分为几个小的区间,然后求小区间的最优解,最后合并,和线性dp有异曲同工之妙,都是求一次状态发程,然后所有的结果都出来了,我也感觉到做dp题,就比如求从第一个数到第n个数的最优解,我们用dp是把i(1<=i<=n)到j(i<j<=n)的最优解都求出来了,最后按自己想知道的直接输出。这次做区间dp比线性dp感觉好的多,做线性dp的时候自己刚接触,其实有的题都有套路,当时不懂,也与自己这个想到一个思路不能快速的表达出来有关,老师说的那些STL中的东西,不是不会用,是想不起来用,我做题就是一开始想朴素的解法,不对了我在想其他的,也是因为其他的比较难想。51假期我正好不回家,也没什么事,宿舍就我一个人,是个刷题的好机会,因为那个山东的程序设计大赛我因为没找到队友而没有参加,几乎每个班的人我都找过了,还是没人,有点遗憾吧,这个假期正好学懂dp,就像老师说的不能松懈。
区间dp中的问题:
区间dp有的是有套路的
memset(dp, 0x3f, sizeof(dp));
for (int i = 1; i <= n; i++) //区间长度为1的初始化
dp[i][i] = 0;
for (int len = 2; len <= n; len++) //枚举区间长度
{
for (int i = 1, j = len; j <= n; i++, j++) //区间[i,j]
{
//DP方程实现
}
}
这只是最基本的,在做题时,可能呈现的代码不是这也,但题思想都一样,分成若干区间来求。经过做题,我发现,区间dp中还是有一些题比较难理解的,也怪自己做题少,接触少。还是要加强训练才行,做刚开始做题,感受不是太多,就感觉比那时候线性dp做题时容易理解一些。
然后我们又初步学习了背包问题
有的背包其实贪心也能做,就是在题中有多个解中求最优的时候,贪心就不行了。
01背包和完全背包
区别:
01背包:就比如有n件价值分别为i的商品,放入容量为w的最优解,而完全背包是不计商品的件数时的最优解。自己也是刚接触,懂得也不多
01背包
基本状态方程:
f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}
f[v]=max{f[v],f[v-c[i]]+w[i]}//表示前i件物品
完全背包:
f[v]=max{f[v],f[v-w[i]]+v[i]}
f[i][v]=max{f[i-1][v],f[i][v-w[i]]+v[i]}
还有就是,背包问题中的状态方程如果要优化,我们可以把数组降维,自己目前还不是太会降维,老师讲的这个降维还是能理解的,最近在军训嘛,然后写博客就拖后了,本来星期五想写的,结果没写完,今天训了一天,晚上上完自习找个空闲才写的,我感觉这几天做题可能会慢一些,毕竟要军训,我白天就不能去看题思考了,就只能全部留给晚上了。慢慢来吧,能多做几个,站了一天了,晚上坐在床上写回代码,然后看着自己能ac何尝不是一种享受。能多写就多写点吧,挤点时间。