背包问题/HDU串1248

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 <stdio.h>  
#include <string.h>  
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;
}


最后抽象出处理一件完全背包类物品的过程伪代码,以后会用到:
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

(六)

这周感觉...唉 真是蹉跎时光啊 我的课怎么有那么多  有一点点崩溃 又不想放弃喜欢的小姐姐

唉 有选择的翘翘课吧 时间不多了  有一些东西是可以补回来的 有一些deadline则是赶不上的 

轻重缓急 加油

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值