倍增与动态规划

多重背包问题

  每种物品有多个,将物品拆成1个、2个、4个、8个…… 2 k 2_{k} 2k个,减少枚举次数。

POJ1742 coins

题意:n种硬币,每种硬币面值为ai,数量为ci。求这些硬币可以组成1~m之间多少种价值。(n≤100 ,m≤100000, ci≤1000)
思路1: 如果将c拆分成1、2、4、8……2k、c-2k,那么也可以组合成1~c任意数目的物品。这样拆分以后时间复杂度为O(nmlogc) (TLE)
正解思路:记录达到每一种状态当前物品使用了多少。注意遍历顺序。时间复杂度O(nm)
在这里插入图片描述

HDU5445 food problem

题意: n种点心,每种点心有能量值k,需要空间u,数量v。m种车,每种车有空间x,花费y,数量z。一份点心可以分装多辆车运,但是需要运完一整份。求达到p能量值的最小代价。(n≤200 , m≤200 , p≤50000)如果答案大于50000,输出TAT,否则输出最小代价。
思路:两次多重背包。第一次求p能量值所需的最小空间,第二次求每一种代价所能达到的最大空间。
第一次背包
在这里插入图片描述
第二次背包
在这里插入图片描述

进制拆分

POI2007 odw_weight 砝码

题意:搬运n个砝码,有m个容器。任何两个砝码都有一个特征,他们的中总有一个的重量是另外一个的整数倍,当然他们也可能相等。(1<=n, m<=100000) 。wi,表示每个容器能够装的最大质量。(1<=wi<=1000000000)。 mj,表示每个砝码的质量。(1<=mj<=1000000000)
思路
这道题的神奇做法:
1. 将砝码看成进制差
2. 将容器按照进制拆分,统计每一位的数量
例如:砝码 2 4 12, 容器18 = 12 * 1 + 4 * 1 + 2 * 1,13 = 12 * 1 + 剩下不要了。(剩下的零头必然不会做贡献,思考一下为什么)
3. 从小到大枚举,如果这一位有,就在总数上减1,否则其上一位退位。

倍增优化DP

NOIP2012开车旅行

题意:小A和小B旅行,城市从1到N 编号,城市i和城市j之间的距离 d[i,j]恰好是这两个城市海拔高度之差的绝对值,即d[i,j]=∣Hi−Hj∣。旅行过程中,小A和小B 轮流开车,第一天小A 开车,之后每天轮换一次。小A 和小 B 的驾驶风格不同,小 B 总是沿着前进方向选择一个最近的城市作为目的地,而小A 总是沿着前进方向选择第二近的城市作为目的地(注意:本题中如果当前城市到两个城市的距离相同,则认为离海拔低的那个城市更近)。他们计划选择一个城市 S作为起点,只能从编号小的城市向编号大的城市行驶,并且最多行驶X公里就结束旅行。在启程之前,小A想知道两个问题:
1.对于一个给定的 X=X0,从哪一个城市出发,小A开车行驶的路程总数与小B行驶的路程总数的比值最小。
2.对任意给定的 X=Xi和出发城市Si,小A开车行驶的路程总数以及小B行驶的路程总数。
思路
  令des[0/1][i][j]表示A/B开车从i城市开始走2^j天到达的城市。
  求des[0/1][i][0]:存入set。从编号小的节点开始处理,查前驱、后继,求最小和次小。处理后记得删除该节点,以保证后续查找时set中元素都比查找元素大。
des[0][i][1]=des[1][des[0][i][0]][0];
des[0][i][j]=des[0][des[i][j-1]][j-1]; (j>=2)
  令dist[0/1][i][j]表示A/B开车从i城市开始走2^j天走过的距离。
dist[0][i][0]=|h[i] - h[des[0][i][0]]|
dist[0][i][1]=dist[0][i][0] + dist[1][des[0][i][0]][0];
dist[0][i][j]=dist[0][i][j-1] + dist[0][des[0][i][j-1]][j-1]; (j>=2)
   倍增查询,看dist什么时候大于x。 然后计算dista和distb就可以了。

CH5702-Count The Repetitions

题意:给s1,s2两个字符串(长度小于100)。字符串a可以由另一个字符串b生成,指b删去一些字符后变成a。给定n1, n2,求m的最大值,使得s2重复n2*m次以后可以由s1重复n1次以后生成。(n1,n2<=1e6)
思路
f[i][j]表示s1的第i位开始,生成s2的2^j次循环所需要的长度。
f[i][0]暴力处理。
f[i][j]=f[ i ][ j-1 ]+f[ (f[i][j-1]+i) % |s1| ][ j-1 ]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值