题目描述:
给你一个整数数组 rewardValues,长度为 n,代表奖励的值。
最初,你的总奖励 x 为 0,所有下标都是 未标记 的。你可以执行以下操作 任意次 :
- 从区间
[0, n - 1]中选择一个 未标记 的下标i。 - 如果
rewardValues[i]大于 你当前的总奖励x,则将rewardValues[i]加到x上(即x = x + rewardValues[i]),并 标记 下标i。
以整数形式返回执行最优操作能够获得的 最大 总奖励。
示例 1:
输入:rewardValues = [1,1,3,3]
输出:4
解释:
依次标记下标 0 和 2,总奖励为 4,这是可获得的最大值。
示例 2:
输入:rewardValues = [1,6,4,3,2]
输出:11
解释:
依次标记下标 0、2 和 1。总奖励为 11,这是可获得的最大值。
解题思路
- 首先对奖励数组进行排序。
- 如果我们决定应用一些奖励,那么按顺序应用它们总是最好的。
- 设dp[i][j](true/false)为第一个i奖励后的状态,表示我们是否能得到j分。
- 如果j−rewardValues[i]<rewardValues[i],则转换为:dp[i][j]=dp[i][j−re-values[i]]。
代码实现
class Solution {
public:
int maxTotalReward(vector<int>& rewardValues) {
ranges::sort(rewardValues);
int n=rewardValues.size();
int MaxSum=2*rewardValues.back();
// MaxSum=2*2000-1也可以
vector<vector<bool> > dp(n+1,vector<bool>(MaxSum+1,false));
dp[0][0]=true;
for(int i=1;i<=n;i++){
int v=rewardValues[i-1];
for(int j=0;j<=MaxSum;j++){
if(j>=v){
dp[i][j]=dp[i-1][j] || dp[i-1][j-v] && j-v<v;
}else{
dp[i][j]=dp[i-1][j];
}
}
}
for(int i=MaxSum;i>=0;i--){
if(dp[n][i])
return i;
}
return 0;
}
};
280

被折叠的 条评论
为什么被折叠?



