有nnn张卡片,每张卡片有name,color,powername,color,powername,color,power属性,给出555个特殊的namenamename,111个特殊的colorcolorcolor。总得分定义为卡片的powerpowerpower之和乘bonusbonusbonus系数,初始是bonusbonusbonus为111,每张卡片满足namenamename是特殊的时候bonus+0.1bonus+0.1bonus+0.1,colorcolorcolor是特殊的时候bonus+0.2bonus+0.2bonus+0.2。需要从nnn张卡内选出555张,使得他们namenamename两两互异,并且使得总得分最大
明显是个分组背包,但如何定义状态?若我们像普通的分组背包,定义f[i]f[i]f[i]为已装iii容量的物品的最大价值,实际上题目的价值是随前面的总价值变化而变化的,难以转移,并且似乎考虑不到所有的状态。造成这一现象的原因是bonusbonusbonus在变化,于是考虑将bonusbonusbonus加入状态,定义f[i][j]f[i][j]f[i][j]为装了容量为iii的物品,此时bonus=10×jbonus=10\times jbonus=10×j的最大powerpowerpower和为多少,这样就能够考虑到所有状态了。显然我们首先需要对卡片按名字分组,于是不妨来一次排序,然后双指针找出同名的一段,枚举加入的卡片为kkk,有
dp[i][j]=max(dp[i][j],dp[i−1][j−val]+a[k].power);dp[i][j]=max(dp[i][j],dp[i-1][j-val]+a[k].power); dp[i][j]=max(dp[i][j],dp[i−1][j−val]+a[k].power);
答案就是max(dp[5][i]+dp[5][i]∗i/10)max(dp[5][i]+dp[5][i]*i/10)max(dp[5][i]+dp[5][i]∗i/10)。需要注意初始化时只有dp[0][0]=0dp[0][0]=0dp[0][0]=0,其他都置为负无穷,以保证转移的源头都是状态(0,0)(0,0)(0,0)
#ifndef stdjudge
#include
#endif
#include
#include
#include
#include
上一篇:2020-java中级面试题