一、题目
二、解法
看到 c c c 这么小肯定要想一些和他有关的算法,可以把 c c c 相同的放在一起 d p dp dp,转移可以按照余数分类(这个套路在小y的背包问题中也见过),选物品就按照权值从大到小来选呗:
d p [ i ] = d p [ j ] + w [ i − j ] ( i % x = j % x ) dp[i]=dp[j]+w[i-j]\space\space(i\%x=j\%x) dp[i]=dp[j]+w[i−j] (i%x=j%x) w [ x ] w[x] w[x] 是单增的,但是他的增加的斜率会一直减小,考虑能不能通过这个性质来搞一点事情。
想优化需要维护一个满足决策单调性的数据结构,在这个结构里当前最优的决策点会逐渐被后面的决策点替代(这个是由 w w w 的性质决定的),那么这个结构里面每一个点都是覆盖一个区间,给这个区间的 d p dp dp 贡献,且这些区间两两不交。
假设我们以前已经维护出了这样的一个决策单调结构,我们来解决插入和弹出的问题:
- 对于弹出队首的操作,我们看下一个决策点的左端点是否覆盖到 i i i,如果是的话那么这个决策点就失效了,因为 w w w 的性质以后他也不会是最优解(我们右端点由于一直在插入是难以维护的,其实有左端点就够用了)
- 对于弹出队尾的操作,我们在队尾的决策点的左端点处进行一个比较,如果 i i i 更优那么队尾失效(和上面弹出的原理类似,由于 w w w 的性质永世不得翻身,而且如果你干不掉队尾就更干不掉其他的)
- 对于插入队尾的操作,如果队列为空,那么直接插入,左端点是 i + 1 i+1 i+