失衡天平-----思维+dp
题目链接
这道题题意是个坑,不是随意取任意多次,不然解不出来,因为任意两堆重量相差m
的物品合到一块重量相差一定还是小于m
,所以这道题的问题转化为将n
个物品分成3
组,分别是 加到左边,不选,加到右边
三种情况,算这三种情况的最大值
f[i][j]
表示前i
个物品,左边比右边重量多j
的最大重量
f[i][j]
可由三种状态转移过来分别是
第i个物品放左边:f[i-1][j-w]+w
这里需要注意的是j-w
小于0
的话相当于右边比左边多j-w
,左边和右边可以互换,等价于左边比右边多j-w
,顾
原式=f[i-1][abs(j-w)]+w
第i个物品不选:f[i-1][j]
第i个物品放右边:f[i-1][j+w]+w
综上:
f [i] [j] = max (f[i - 1] [abs( j - w) ]+w,f[i-1][j],f [i-1][j+w]+w)
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 10010;
int f[110][N];
int n,m;
int a[110];
int main()
{
cin>>n>>m;
int sum=0;
for(int i=1;i<=n;i++)cin>>a[i],sum+=a[i];
memset(f,-0x3f,sizeof f);
f[0][0]=0;
for(int i=1;i<=n;i++)
{
for(int j=0;j<=sum;j++)
{
f[i][j]=f[i-1][j];
int maxv=max(f[i-1][abs(j-a[i])],f[i-1][j+a[i]]);
f[i][j]=max(f[i][j],maxv+a[i]);
}
}
int res=0;
for(int i=0;i<=m;i++)res=max(f[n][i],res);
cout<<res<<endl;
}