sincerit 王者荣耀(01背包)

链接:https://ac.nowcoder.com/acm/contest/318/J
来源:牛客网

题目描述
“无论何时何地,都会遵守约定”。“奋力逃吧”。“关于取下敌人性命这件事,也从不失约”。

小懒虫zmx平时最喜欢玩的游戏就是《王者荣耀》,在这款游戏中它也最喜欢百里守约这个英雄。最近,zmx准备冲国服百里,所以它开始练英雄,你有很多个时间段来练习英雄,每个时间段有一个开始时间点和结束时间点,以及可以获得的熟练度。不过现在你可以随意修改任意练习时间段的开始和结束时间点,但是你不能修改时间段的长度和获得的熟练度!由于要学习,你只能在固定时间段玩游戏,问你最多可以获得多少熟练度?

例如:你可以把[2,3),修改为[1,2)或者[3,4)等等,他们的长度都是1。

注意:对于某个时间段,不管你有没有修改,必须练完整个时间段长度才能获得熟练度!

输入描述:
第一行,三个整数n,S,T(0<n<=1000,0<S<T<1000)代表n个时间段和你能在[S,T)时间段内玩游戏。

接下来n行,每行三个整数a,b(0<a<b<1000),c(0<c<1e7),用空格分开,代表时间段起始时间[a,b)和可以获得的熟练度。
输出描述:
输出一行,包括一个整数,表示zmx能获得的最大熟练度。
示例1
输入
复制
3 1 3
1 3 5
2 4 6
4 7 8
输出
复制
6
示例2
输入
复制
5 1 5
1 2 1
2 3 2
1 3 3
3 4 2
3 6 4
输出
复制
7

思路:
本题为一个裸的01背包,背包的大小为T-S。
第 i 个时间段可以看成一个物品,这个物品的体积w[i]=b[i]-a[i],价值v[i] 为熟练度c。
那么dp[i][j]就表示着在前 i 个时间段里花费 j 的时间练英雄能得到的最大熟练度。
状态转移方程为:
For i = 1;i <= n;i++
For j = w[i];j <= sum;j++
dp[i][j] = max(dp[i][j],dp[i-1][j-w[i]]+v[i]);
当然也可以考虑用滚动数组来优化一下空间复杂度,此时的状态转移方程为:
For i = 1;i <= n;i++
For j = sum;j >= w[i];j-- dp[j] = max(dp[j],dp[j-w[i]]+v[i]);
待实现

猜你喜欢

转载自blog.csdn.net/sincerit/article/details/85227859