本文共 2442 字,大约阅读时间需要 8 分钟。
http://www.cnblogs.com/William-xh/p/7305877.html 真的是非常非常非常非常好的教程! (一)小测试 https://blog.csdn.net/hpugym/article/details/43882781 这个题有点小别扭,就是把value和price反过来了 【代码片】 for (int i = 0; i < k; i++) {//对于背包里的每个包,都要更新一下他们的状态吧= =- //要明白这个包是自从下面往上面,然后是从右边往左边生成的,额可以 //别的其实你也是浪费了== - orx for (int j = m; j <=price[i]; j--) {//对于每一个i更新的一行啊....而且只要更新 //而且只要更新prcie[i]之后的就可以了,否则放不下去. sum[j] = max(sum[j],sum[j - price[i]] + wight[i]); //【是针对每个物品遍历的,所以里面是i啊,j只是那个状态而已i吧】 //啊,有点像是痕迹吧,虽然说是这样生成的,但是其实每次一行那样更新过去 //后面的就没意义了... 就是一行在始终动态更新着变化的 } } j-price[i],也只是坐标而已吧,(排除了123完全放不下的情况-那些就让其他的来填满吧-然后它的触角还是可以伸到123那些啊= -) 啊!for (int j = m; j <= price[i]; j--) !!!只要遍历到这里就可以了,别的都是浪费的.. 因为j更小的话根本装不下啊 但是1但是!这个等号嗷带着的,别忘了 【以及】从01背包往上面跑了一步,就是如果是一件的很多样物品,不如直接存贮一个cnt然后用k记录一下总数...方便快捷 (二)隐身(引申) 上次的小比赛有个题目是这个,再琢磨一遍吧(代码有参考)
#include最后抽象出处理一件完全背包类物品的过程伪代码,以后会用到: 1 void CompletePack(int cost, int weight) 2 { 3 for (int v = cost; v <= V; v++) 4 f[v] = max(f[v], f[v - cost] + weight); 5 } 感觉这道题目用背包做是肯定不会错的.. 【核心代码在这2行】 for (i = 0; i <= 2; i++) for (j = w[i]; j <= n; j=j+10) dp[j] = max(dp[j], dp[j - w[i]] + w[i]); 至于为什么...我隐隐约约的感觉,可能和顺序有关? 上文那个,倒着放进去,从最大的开始就已经拦腰截断了,所以只能放一次,下面这个正着开始就 因为,按照http://www.cnblogs.com/William-xh/p/7305877.html的表格,这张表是至底向上,(?)好像是从右到左 虽然可以化成一行一行的表格,但是其实完全可以不要坐标(v[i][j])因为这个表是随时实时更新的..... 那么其实你从i开始到后面n为止,前面的也被更新了.... 就拿150来说 到350的时候可以选择dp[150]这个还是在同一行的for循环更新的 但是,如果倒着从n就开始生成,就不能使用之前更新过的状态了... printf("%d\n", n - dp[n]); (三) 至于,150 200 350 是无限的,塞进去更新的话也用得到吧,比如某些150到达不了的地方,200就可以达到最优.. 但是350在都价值和重量都一样的情况下,就没法到达最优了,完全可以被另外两个取代... (四) 还有就是,如果一个物品花费高,value低,什么时候都可以用花费低,value高的另一个物品来填充(剪枝) 因为哪怕是窟窿,也可以有另一个来补,上一个题的话就是,350其实被150,200抵消之后可以不看= - 如果问题是150的重160,200的重130,200就没用了= - 如果是150的重150,200的重量150,还是用150能够到达最大的= -(只看价值,背包空不空是另外的事情吧,虽然这个题的话是个谬论..用150元达到了200的价值,balaba) 如果150的重150,200的200,....350就没用了啊 啊 QAQ (五) 本质其实是动态规划问题...搞明白了背包可以有很多变种= = 动态规划才是根本啊T T#include int w[3] = { 150,200,350 };//w[i]既是花费的代价,也是获得的价值 int dp[10005];//dp[i][j]表示在购买到i件物品,用j块钱所获得的最大价值.最后n-dp[3][n]; int max(int a, int b){ return a>b ? a : b;}int main(){ int T, i, j, n; scanf_s("%d", &T); while (T--) { scanf_s("%d", &n); memset(dp, 0, sizeof(dp)); for (i = 0; i <= 2; i++) for (j = w[i]; j <= n; j=j+10) dp[j] = max(dp[j], dp[j - w[i]] + w[i]); printf("%d\n", n - dp[n]); //dp[N]J仅仅是存着的这个状态而已吧,然后记录的是数值,一样的 //= = } return 0;}
(六)
这周感觉...唉 真是蹉跎时光啊 我的课怎么有那么多 有一点点崩溃 又不想放弃喜欢的小姐姐
唉 有选择的翘翘课吧 时间不多了 有一些东西是可以补回来的 有一些deadline则是赶不上的
轻重缓急 加油