您的位置:首页 > 其它

soj2222_01背包变形

2017-08-15 20:41 148 查看
简介题意:

http://acm.scu.edu.cn/soj/problem.action?id=2222

一个游戏,里面有多种水果,每种水果可以加hp和score。先加满缺失的hp才可以加score,所以给出几个水果,怎样达到最后得到score最大。

反过来看,hp加满才加score,那么使得hp加满/溢出的最小score和正是我们所需,因为sumscore是一定的,用于hp消耗的score越小,则用于加分的score越多。

(所需hp1~1000,水果hp1~10000,水果score1~10000)

所以列出式子:

用因为题目中水果的hp属性最大为10000,所以最大满足题意的所有水果hp之和应该是hp+10000(因为要至少补满血为hp,再加上最大值10000,所有满足题意加满hp水果都包含在内)

scorenow[j]表示相加血量为j的水果、的最小score和(有点绕口,就是hp相加为j的水果们,这些水果的score之和达到最小时候,score是多少)

for(int i = 0; i < species ;i++)
for(int j = hp+10010; j >= food[i][0]; j--)
{
scorenow[j] = min(scorenow[j], scorenow[j-food[i][0]] + food[i][1]);
if(scorenow[j] < minfscore && j >= hp)
minfscore = scorenow[j];}
scorenow[j-food[i][0]]+food[i][1] 表示,没有算上这个水果的score+本水果的score。

scorenow[j]则表示已经加上本水果的score,而j血量也已经包含了本水果的hp。

所以注意!!!scorenow[j] 的意思是血量j算上了food[i],第i个水果,这些hp加起来为
j 的水果的score之和。

这两种就是讨论hp之和一定为j的时候,那些水果的score之和更小一点就要哪个

之后我们判断 j>=hp,满足题意的情况下,最小的minfscore,消耗score最小的水果用来加hp,可以得到更高的分数。

也可以写成:

for(int i = 0; i < species ;i++)
for(int j = hp;j >= 0;j--)
scorenow[j + food[i][0]]=min(scorenow[j + food[i][0]], scorenow[j] + food[i][1]);
for(int i = hp; i <= hp+10010;i++)
minfscore = min(scorenow[i],minfscore);
这样看也许更简单明了。

scorenow[j+food[i][0]] 当前血量再吃一个food[i]加血的时候,这个时候的score值(此时是scorenow是已经加上了本水果的搜查人的!!!!)。和直接 j 血量,把food[i]加分的socre值,哪个更小就要哪个。

这种水果来加血则浪费的score(用来补血,所以浪费score)=(当前这个血量的最小消耗score 或者  血量就差本水果的hp,再加上本水果之后浪费的score)哪种分小
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  背包 soj