小李打怪兽 01背包

在网上看到的题目,觉得有趣且不会写…
就看了看题解,记录下思路吧
大概意思是 给出n堆物品 要求分成两堆 a,b
a>=b (b可以为0)
使得a与b的平方差最小 即pow(a,2)-pow(b,2) 最小
首先a是大于等于b的 所以答案肯定是非负
之后你想,假设sum为所有物品之和且sum==a+b
如果要求答案最小 那就是a尽可能小,b尽可能大
但是a是大于等于b的 所以就需要他们尽量靠近sum/2就好了
我们可以化简下式子
ans=a2-b2,sum=a+b 所以a=sum-b 代入可以得到
(sum-b)2-b2=sum2-2xbxsum+b2-b2
所以为 sum2-2xbxsum sum固定 所以答案尽可能小就需要要求
b尽可能大 所以我们直接开一个sum/2体积的背包 求出每种体积的背包所能够储存的最大价值 答案为b=dp[sum/2]即可

int n=read();
int sum=0;
rep(i,1,n)
{
    a[i]=read();
    sum+=a[i];
}
rep(i,1,n)
{
    for(int j=sum/2;j>=a[i];j--)
        dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
}

最后b等于dp[sum/2] 再依靠a,b的关系求出答案就好了

猜你喜欢

转载自blog.csdn.net/leoxe/article/details/105091207