Time Limit: 1 second

Memory Limit: 128 MB

【问题描述】

Mini进入洞口前自然要先来到镇里的装备店买些装备。买每件装备都需要付出一定的体力点,同时也会获得一定的能力点(每种装备

都可以买无限次^_^,但人的体力点可是有限的哦^_^)。当同种装备挑选的数量>=5时,除了挑选这些物品所获得的能力点之外

还会获得额外的Q*K(K表示挑选的数量)点的能力点。但是,同样的,Mini也会付出更多的体力点,即体力点还将多付出Q*K(K

表示挑选的数量)点。挑选的物品越多,产生的力量就越大,体力点也会付出越多。不过,这额外获得的能力点和付出的体

力点是可以不要的。为了能获得最大的能力点,同时也不至于使自己过分劳累(体力恰好为0不算过分劳累),Mini应该如何购

买装备呢?

【输入格式】

第一行,两个数N和M,N表示有多少种装备,0<=N<=340,每种装备可以买无限次。M表示Mini所拥有的体力点数,0<=M<=500。

以下N行,第I行三个数, WI,QI,Q。WI表示买第I个装备所付出的体力点,QI表示买第I个装备能获得的能力点,Q表示当第I个装备

的数量>=5时所产生的共鸣点。1<=WI<=9000,0<=QI<=9000,0<=Q<=9000。

【输出格式】

一个数,表示在保证Mini不会过分劳累的情况下所能买到的最大能力点

Sample Input

5 87
35 48 7
3 57 6
45 9 24
3 4 0
5 7 7

Sample Output

1653

【题解】

这题比较烦的地方是,多出来的额外能力点。但是其有说,如果不想要的话,可以不用花费额外的体力获得额外的技能点。也就是说。我可以买一个东西买了6个,但是不消耗额外体力获得5*q+6*q能力点的情况是允许的。

考虑到这种情况。我们先不要管那些额外技能点。

先按照给出的w[i],c[i]进行完全背包的操作。

会有两层for

for i 和for j

j是容量。

然后我们不能等这两层循环都结束之后再去处理额外能力点的问题。而应该在i层循环中一边处理不考虑额外能力点的完全背包问题一边在完全背包结束后考虑额外能力点的问题。

因为额外能力点也是一个完全背包。所以其更新方式也是顺序更新。

同时在不考虑额外能力点的完全背包中。要记录f[j]对应的num[j],即f[j]是在买了几个装备后获得的值。然后在单独考虑额外能力点的完全背包中。我们同样枚举j,只有在num[j] >=4的时候才尝试更新,即如果num[j] >=4 则看一下ju = j + (num[j]+1)*q[i] 是否大于m,如果不大于,则查看

f[j+(num[j]+1)*q[i]] 和 f[j] + (num[j]+1)*q[i]的大小关系。如果前者小于后者,则更新前者。

同时修改num[j+(num[j]+1)*q[i]]的值为num[j]+1;

因为是以j为更新起点,所以是num[j] >=4,因为再买一个装备就变成5了。

这段题解可以根据代码来理解。

【代码】
#include <cstdio>
#include <cstring>
int n,m,w[400],c[400],q[400],f[600] = {0},num[600] = {0};

int main()
{
//freopen("F:\\rush.txt","r",stdin);
scanf("%d%d",&n,&m);
for (int i = 1;i <= n;i++)
scanf("%d%d%d",&w[i],&c[i],&q[i]);
for (int i = 1;i <= n;i++)
{
<span style="white-space:pre">			</span>memset(num,sizeof(num),0);
for (int j = w[i];j <= m;j++) //先进行一次完全背包 不考虑多出来的额外技能点
if (f[j] < f[j-w[i]] + c[i])
{
f[j] = f[j-w[i]] + c[i];
num[j] = num[j-w[i]] + 1;
}
for (int j = 0;j <= m;j++) //考虑额外技能点,因为也是完全背包所以顺序枚举
if (num[j] >= 4) //如果数目大于等于4再更新一个装备就能>=5了
{
int ju = j+(num[j]+1) * q[i]; //这是所需要的花费
if (ju > m) continue;
if (f[ju] < f[j] + q[i] * (num[j]+1))
{
f[ju] = f[j] + q[i] * (num[j]+1); //加上相应的价值 看看是否更优
num[ju] = num[j] + 1; //同时要更新数目
}
}
}
printf("%d",f[m]);
return 0;
}

【t067】补充装备的更多相关文章

随机推荐

  1. solr/lucence和关系数据库的混合使用

    我们知道solr提供了一个DIHandler,提供将关系数据库中的数据导成索引,然后使用solr查询. 对于一个大表中关联数个小表的查询,这非常耗费时间. 我的思路是: 1. 将一个大表做成索引,使用 ...

  2. Redis原理(一)

    基础和应用 1.Redis是远程调用技术的首字母缩写. 2.Redis可以用来做什么? Redis可以用来做缓存. 分布式锁 3.Redis的应用举例 记录帖子的点赞数.评论数和点击数.(使用HASH ...

  3. loadrunner监控apache服务

    一.apache配置步骤(假设apache服务已安装) 1.使用find / -name httpd.conf命令查找httpd.conf文件 2.使用cd opt/lampp/apache2/con ...

  4. 【Codeforces Round #446 (Div. 2) C】Pride

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 想一下,感觉最后的结果肯定是从某一段开始,这一段的gcd为1,然后向左和向右扩散的. 则枚举那一段在哪个地方. 我们设这一段中所有的 ...

  5. 逻辑与和逻辑或:&& 、||

    逻辑或:首先看左边是真还是假(除了那5个都是真),如果为真,返回左边值,如果为假,返回右边的值 逻辑与:和逻辑或相同,先看左边的值是真是假,如果左边为真返回右边的值,左边为假返回左边的值 在两者同时出 ...

  6. JS学习笔记 - 点击、回车、ctrl+回车提交留言

    疑点: oTxt1.onkeydown = function (ev) 为什么这里的onkeydown = function有变量 (ev),前面onclick函数没有? window.onload ...

  7. Spring MVC学习总结(1)——Spring MVC单元测试

    关于spring MVC单元测试常规的方法则是启动WEB服务器,测试出错 ,停掉WEB 改代码,重启WEB,测试,大量的时间都浪费在WEB服务器的启动上,下面介绍个实用的方法,spring MVC单元 ...

  8. ubuntu,右键添加在终端中打开

    右键中添加"在终端中打开" 在终端输入  sudo apt-get install nautilus-open-terminal 重新启动, 进入操作系统就会发现单击鼠标右键就会出 ...

  9. jQuery笔记---选择器(二)

    1.选择器练习: 1)查找UL中的元素的内容 格式:$(“ul li:XX”).text() XX:代表方法 比如:获取到第一元素,然后获取当中的值 $(“ul li:first”).text() 获 ...

  10. POJ3984 迷宫问题 BFS

    看题传送门:http://poj.org/problem?id=3984 BFS水一发 明天帮学弟挑电脑顺便去玩.接下来几天好好看数据结构.嗯哼. 这题标准的BFS应用,唯一需要注意的是需要输出中间的 ...