4012: 分赃不均(kas)

题目描述

 

仗助、亿太、胖重分赃不均闹起来了。

仗助和亿太拿着n张面值分别为a[i]的钞票决定均分,他们希望把钞票分成金额相等的两份,且未分配的剩余钞票总金额最小。

对于剩余的部分,则用替身能力复制成两倍再均分(大雾)。

求他们最终各自能带回家的金额。

 

 

输入

 

第一行一个正整数n。
接下来每行输入n个正整数,第i个数代表a[i]。

 

 

输出

 

   一行一个正整数,每个人能带回家的总金额。

 

 

样例输入

	样例输入1
4
2
3
1
6
	样例输入2
	5
2
3
5
8
13

样例输出

样例输出 1
6
样例输出 2
18

提示

 

提示

对于50%的数据,n<=13。

对于70%的数据,n<=50,总金额sum<=100。

对于100%的数据,n<=500,总金额sum<=100000。

样例解释

   样例1:2+3+1=6,分配完毕,6+0=6;

   样例2:5+8=13,剩余2、3未分配,13+2+3=18。

题解:

dp,f[i][j]表示前i张钞票,两边相差为k,最多的共有的部分,转移需要分类讨论,即将第i+1张钞票给哪一边,在这边不说明了。

#include
#include
#include
#include
#include
#include
#include
#define mod 200000
using namespace std;
int n,a[505],g[100005],f[100005],sum,sxtc;
int l,r;
struct no{
    int x,bs;
}q[200005];
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);sum+=a[i];
    }
    g[0]=0;int la=0;
    l=0,r=1;q[r]=(no){0,0};
    for(int i=0;i<=sum;i++)f[i]=-1;
    sxtc=0;
    while(l!=r){
        no t=q[++l];l=l%mod;
        if(t.bs==n)break;
        if(t.bs>la){
            sxtc+=a[t.bs];
            for(int i=0;i<=sxtc;i++)g[i]=f[i],f[i]=-1;
            la=t.bs;
        }
        int i=t.bs+1;
        if(g[t.x]>f[t.x]){
            f[t.x]=g[t.x];
            q[++r]=(no){t.x,i};r=r%mod;
        }
        if(g[t.x]>f[t.x+a[i]]){
            f[t.x+a[i]]=g[t.x];
            q[++r]=(no){t.x+a[i],i};r=r%mod;
        }
        if(t.x>=a[i]){
            if(f[t.x-a[i]]

 

你可能感兴趣的:(4012: 分赃不均(kas))