分赃不均

题目描述

仗助、亿太、胖重分赃不均闹起来了。
仗助和亿太拿着n张面值分别为a[i]的钞票决定均分,他们希望把钞票分成金额相等的两份,且未分配的剩余钞票总金额最小。
对于剩余的部分,则用替身能力复制成两倍再均分(大雾)。
求他们最终各自能带回家的金额。

题解

我们思考 D P DP DP,傻逼 D P DP DP就是 f [ i ] [ j ] [ k ] f[i][j][k] f[i][j][k]表示 j j j, k k k的最小差值,然而我们其实并不关心 j j j, k k k的具体值。
我们要有坚定不移的精神,看什么恶心就把什么拿到维度里面去维护
f [ i ] [ j ] f[i][j] f[i][j] j j j为差值为 j j j时的最大值,那么答案就是 s u m − f [ n ] [ 0 ] / 2 sum-f[n][0]/2 sumf[n][0]/2,其次我们的差值并没有分是A和B还是B和A,所以我们转移的时候加个abs

代码

#include <bits/stdc++.h>
#define maxn 200005
#define INF 0x3f3f3f3f
using namespace std;
int n,a[maxn],tax[maxn],mx,sum;
int f[2][maxn],pos=1;
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),sum+=a[i],mx=max(mx,a[i]);
    memset(f[0],0x8f,sizeof f[0]);
    memset(f[1],0x8f,sizeof f[1]); 
    f[0][0]=0;
    for(int i=1;i<=n;i++){
        for(int j=0;j<=mx;j++){
            f[pos][j]=max(f[pos^1][j],max(f[pos^1][abs(j-a[i])],f[pos^1][j+a[i]])+a[i]);
        }
        pos^=1;
    }
    cout<<sum-f[pos^1][0]/2<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jarden_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值