21.5.15 周末总结

01背包是所有背包的基础,其他所有背包问题都是在此基础上做出更改,或者直接转化为01背包的问题。
所有这些背包种类的模板原型好理解,但是这些题目是真难写(秃头👨‍🦲)

N:混杂了一个区间dp,还是贪心什么的
题型没有什么特别,需要注意的是不能用string 会runtime error,得用char型的数组(string据说可以开到六万),为什么不行,不知道。

D:求第K个最大值(01背包)(看了题解也不容易理解)
换成二维数组f[ i ][ j ]表示容量为i的第j个最大值;
因为每个物品仍然还是两个选择,选或不选,用两个数组a,b辅助保存下两种选择下的前k大方案,然后再在一个循环里面找出从1到K的最合适的值保存下来
总结,我们可以学到要求其中的某个最值的时候,要保存所有相对应的路径

😀 一、完全背包

J: 组合数+(超大数
方法: 整数拆分(把一个大数用两个数组来存)

long long int mod=1000000000000000000;
f1[j]=f1[j-i]+f1[j]+(f2[j-i]+f2[j])/mod;
f2[j]=(f2[j-i]+f2[j])%mod;

M: Investment(钱数一直改变)
投资问题,给出初始资金和总年数,然后给出每个物品的购买价格和每年的利益,求最后能得到的最大钱数
这个题的特殊之处在于,总钱数是本金加上利润,每年都在改变,所以要一直更新钱数,还有一个要注意的点是,数值的大小,题目提示本金和物品的购买价格都是1000的倍数,然后我们就把每个数都除以1000即可
对于数据处理,每个题都有不同的要求,可以适当的加加减减,乘乘除除,还有上面的J题一样,数值特别大的话就用两个数组来处理

V: Piggybank
有一个存钱罐,自身有重量,存满之后有另一个重量,给出每种硬币的重量和价值,求(恰好装满)后的(最小)价值是多少,恰好装满和最小价值都是和初始化有关。

😀 二、多重背包(每种件数不同)

给出了每件物品的价值和体积,但是每种物品的个数有限制且不等,本来是与完全背包有联系,在原来的二重循环的基础上,再加上一重个数的限制循环,显然三重循环不够优化,这就要用到了二进制的思想转化,实质上就是转化为01背包。

既然个数有了限制,就可以把所有的物品都拆开然后进行循环,用01背包来处理每一件货物,这也是降低了复杂度
由于拆开以后的个数可能有点多,那就不能简单的一个一个拆,可以将第i种物品分成若干种,每种都有2的k次方个,即1.2.4.8…和剩下的
这样我们相当于把几个物品合成一个,对应的价值和质量也就翻了相应的倍数。

(<font color=blue size=4>二进制转化的过程</font>)
k=0;
    for(int i=1; i<=n; i++)
    {
        cin>>x>>y>>s;
        t=1;
        while(s>=t)//数量
        {
            v[++k]=x*t; //价格
            w[k]=y*t; //价值
            s-=t; //最大数量的剩余
            t*=2; //1,2,4,8....
        }
        v[++k]=x*s;
        w[k]=y*s;
    }

P: Space Elevator
给出n种石头,和每种石头的高度以及这种石头不能超过的最大高度,和数量,求能组成的最大高度
毫无疑问,限制高度小的先放,等价于排序
最后仍然是多重背包问题,这个没有用二进制转换,普通的套路,第一重(1-n),第二重(每个高度到限制高度),第三重(数量从1到c)

😀 三、分组背包(每组多种)

(1) 每组最多选一件

三重循环:
//组数
//体积
//每组件数

Y:I love sneakers !
有一个人m块钱,要去买鞋,k种牌子,每种牌子有它的价格和相对应的卖出的价值,求最后可买的最大总价值(每种不会买两次)
这个题还有答案是当买不起的时候要输出“impossible”,所以额外的要用-1和0来判断每件可不可买,两个限制条件,如果这一种类的上一件(即0件,前提给所有0件赋值)可买,那么就更新最值,再判断上一种的上一件是否可买,然后取最值。

(2) 每组至少选一件

😀 四、混合背包()

就是把01背包和完全背包和多重背包放在一起, 方法就是根据物品的类别选用顺序或者逆序即可。
简单的01+完全:

for(int i=1;i<=n;i++)
{if(01背包) {for(V…) }
else if(完全背包){for(…V)}

没题

心得: 最近感觉没动力了,做题都是在做任务一样,没有自己想去主动获得知识动力了,什么时候才能恢复?

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值