经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C » 查看文章
Topcoder SRM 563 Div1 500 SpellCards
来源:cnblogs  作者:自为风月马前卒  时间:2018/10/12 9:45:35  对本文有异议

题意

[题目链接]这怎么发链接啊。。。。。

\(n\)张符卡排成一个队列,每张符卡有两个属性,等级\(li\)和伤害\(di\)
你可以做任意次操作,每次操作为以下二者之一:

把队首的符卡移动到队尾。

使用队首的符卡,对敌人造成\(d_i\)点伤害,并丢弃队首的\(l_i\)张符卡(包括你所使用的符卡)。如果队列不足\(l_i\)张符卡那么你不能使用。

求出造成的伤害的总和的最大值。

\(1<=n<=50, 1<=li<=50, 1<=di<=10000\)

Sol

结论:如果选出的卡牌满足\(\sum l_i <= N\),那么总有一种方案打出这些牌

背包一下就van了

这个结论虽然看起来很显然 但是在考场上应该不是那么好发现吧

简单的证明一下:

序列上的问题比较难处理,我们把它们放到环上,这样可以消除操作1的影响

显然,选出的卡牌一定存在相邻的两个满足\(i - j > l_i\),也就是其中一个释放技能后不会干掉另一个(否则一定\(>N\))

我们把这张卡牌用掉,于是问题变成了一个相同的子问题。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. inline int read() {
  4. char c = getchar(); int x = 0, f = 1;
  5. while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
  6. while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
  7. return x * f;
  8. }
  9. int f[100];
  10. class SpellCards{
  11. public:
  12. int maxDamage(vector<int> l, vector<int> d) {
  13. int N = l.size();
  14. for(int i = 0; i < N; i++)
  15. for(int j = N; j >= l[i]; j--)
  16. f[j] = max(f[j], f[j - l[i]] + d[i]);
  17. return *max_element(f + 1, f + N + 1);
  18. }
  19. };
  20. int main() {
  21. int N = read();
  22. vector<int> l, d;
  23. for(int i = 1; i <= N; i++) l.push_back(read());
  24. for(int i = 1; i <= N; i++) d.push_back(read());
  25. cout << SpellCards().maxDamage(l, d);
  26. }
  27. /*
  28. 7
  29. 1 2 2 3 1 4 2
  30. 113 253 523 941 250 534 454
  31. */
 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号