Problem Description
Nowadays, we all know that Computer College is the biggest department in HDU. But, maybe you don’t know that Computer College had ever been split into Computer College and Software College in 2002.
The splitting is absolutely a big event in HDU! At the same time, it is a trouble thing too. All facilities must go halves. First, all facilities are assessed, and two facilities are thought to be same if they have the same value. It is assumed that there is N (0
题意:
给出每个物体的价值和物体的数量,如何分使得A,B所得价值最接近并且A的价值不能小于B
tip:
分两份,尽可能相等,每个最大就是sum/2,把v改成这个就是多重背包的裸题啦
单调队列优化的多重背包模板?:
首先每个物品添加就是d,d+v[I],d+2*v[I]…,d+num*v[I](不超过V)
(d从0-v[I]-1)而且每个只能从相同的d的前面状态转移而来,那么我们就可以外层枚举d了,里面是加多少个v的循环,而假如是p个v,就相当于需要p个,如果一共就k个i物品,那么转移而来的点不能是k-p之前的,因为这样就会加多了,所以记录dp的队列要出队头,一共记录不多于k个,而每次我们要找的就是这k个中最大值,再拿一个单调队列记录一下,从大到小递减,如果dp队列出的队头是当前的最大值,就要在这个队列也出队头,其他的情况就是这个单调队列的头来更新当前dp。。而这个放在dp队列里的和我们正常的dp[j](放j体积的最大价值)不一样,因为还是要保证一点,队列里记录的是整个i物品加之前的值,因为更新的时候不能重复,那怎么做到呢,就是先用这个值-当前放多少个I的体积 这样放到队列里,更新下一个的时候直接+当时多少个I的体积就好了,而因为每个都是+i*num所以不影响单调性的。。
void get_mul(int i){
for(int d = 0 ; d < v[i] ; d++){
int stq = 0,edq = -1,stm = 0,edm = -1;
for(int k = d,cnt =0 ; k <= V; k += v[i],cnt++){
if(edq == stq+num[i]){
stq++;
if(getmax[stm] == q[stq-1])
stm++;
}
int tmp = dp[k]-cnt

这篇博客探讨了在计算机学院的历史背景下,如何处理设施分配的问题,转化为一个多重背包问题。通过介绍题意和提示,文章重点讨论了如何使用单调队列优化解决多重背包问题的算法模板,包括如何构建转移状态和利用单调队列保持最大价值的有效搜索。此外,还提到了二进制log的做法作为另一种解决方案。
最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



