Codeforces Round #214

A和B都是简单题

C. Dima and Salad

题意:给出n个a[i],再给出与a[i]对应的b[i],求一组序列,在sum(a[j]) = k * sum((b[j]) (1 <=j <= n)时,sum(a[j])最大。

思路:就是一个代价有负数的01背包,求代价刚好为0时的最大值。我们来看,如果代价全是非负数时,我们的代码:

	for(int i = 1;i <= n;i++)
		for(int v = max;v >= cost[i];v--)
			dp[v] = max(dp[v],dp[v - cost[i]] + value[i])
此时,如果cost[i]是负数,那么,dp[v]中的v就有可能是负的;当cost[i] >= 0时,跟经典的01背包没有差别,如果dp[v]中v允许为负,以v = -9为例,dp[-9] = max(dp[-9 - cost[i]] + value[i]);而如果cost[i] < 0,计算dp[v]的顺序,即第二层循环就不能一样了,为什么,因为当cost[i] < 0时,-9 - cost[i] > -9,也就是说,应该是从比-9更大的代价上转移来的。所以,第二层应该为

for(int v = 0;v <= max + cost[i];v++)

好了,循环顺序搞清楚了,我们再来看dp[v],编程语言不允许v < 0,那我们可以将v水平右移变成v + x,本来 v = 0的时候是原点,现在原点相应变成v + x。然后就可以跟01背包一样处理了。

D. Dima and Trap Graph

题意:每条边有一个范围[l, r],我们有一个忠诚度x,当l <= x <= r时,就可以通过这条边,现在要从点1走到点n,问x最大的区间是多少,即lt <= x <= rt,求max(lt - rt)。

思路:其实,这题最重要的特性就是,lt和rt必定是某一条或某两条边的l 和 r。由此特性,我们可以对所有边的左区间值进行遍历,遍历时,对右区间进行二分,然后就看能否用此时查找的区间值从1走到n就行了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值