https://leetcode-cn.com/problems/last-stone-weight-ii/
思路:考虑
d
p
i
,
j
dp_{i,j}
dpi,j表示处理前
i
i
i个石块后剩余石块重量总和为
j
j
j的状态是否存在。那么对于
d
p
i
−
1
,
j
dp_{i-1,j}
dpi−1,j,我们可以把第
i
i
i块石头加进来但不做任何处理,也可以粉碎第
i
i
i块石头(这取决于
s
t
o
n
e
s
i
stones_i
stonesi和
j
j
j的大小),因此有转移方程:
d
p
i
,
j
+
s
t
o
n
e
s
i
=
d
p
i
−
1
,
j
d
p
i
,
a
b
s
(
j
−
s
t
o
n
e
s
i
)
=
d
p
i
−
1
,
j
dp_{i,j+stones_i}=dp_{i-1,j} \\ dp_{i,abs(j-stones_i)}=dp_{i-1,j}
dpi,j+stonesi=dpi−1,jdpi,abs(j−stonesi)=dpi−1,j
可利用滚动数组把空间降到一维,结果就是第一个为真的
d
p
i
dp_i
dpi。
class Solution {
public:
int lastStoneWeightII(vector<int> &stones) {
int sum=0,n=stones.size();
for(int i=0;i<n;i++)
sum+=stones[i];
vector<int> dp(sum+1);
dp[stones[0]]=1;
for(int i=1;i<n;i++)
{
vector<int> dp2(sum+1);
for(int j=0;j<=sum;j++)
if(dp[j])
dp2[abs(j-stones[i])]=dp2[j+stones[i]]=1;
dp=move(dp2);
}
for(int i=0;i<=sum;i++)
if(dp[i])
return i;
return 0;
}
};