FZUOJ Problem 2178 礼品配送

Problem 2178 礼物分配

题目链接: Click Here~

Problem Description

在双胞胎兄弟Eric与R.W的生日会上,他们共收到了N个礼物,生日过后他们决定分配这N个礼物(numv+numw=N)。对于每一个礼物他们俩有着各自心中的价值vi和wi,他们要求各自分到的礼物数目|numv-numw|<=1,而且各自所衡量的礼物价值的差值|sumv-sumw|尽可能小,如今他们想知道最小的差值是多少。

 Input

第一行为一个整数表示数据组数T。 接下来T组数组,每组数据第一行为一个整数N。

(N<=30) 第二行有N个整数,表示Eric所衡量的每一个礼物的价值vi。(1<=vi<=10000000) 第三行也有N个整数,表示R.W所衡量的每一个礼物的价值wi。(1<=wi<=10000000)

 Output

对于每组数据。输出最小的差值。

算法分析:

能够easy想到的方法是直接枚举暴力。如今对第一个人来分析,每一个物品都有选或者不选的可能。

这种话总情况是2^30次方。肯定超时。想着怎么优化。

非常easy的想到了二分搜索。就是折半查找。

思想就好是先预处理出前一半部分的结果。

然后,在用前面的结果推断后面的情况。这样就能够优化到了2^15次方了。

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <cstring>
using namespace std;

typedef __int64 LL;
const int INF = 1 << 30;
const int MAXN = 40;
vector<int> num[MAXN];
int vi[MAXN],wi[MAXN];

int main() {
   int n,T;
   scanf("%d",&T);
   while(T--) {
       scanf("%d",&n);
       for(int i = 0;i < n;++i) {
           scanf("%d",&vi[i]);
       }
       for(int i = 0;i < n;++i) {
           scanf("%d",&wi[i]);
       }

       for(int i = 0;i <= n;++i)
         num[i].clear();

       int n2 = n/2;
       int cnt,sum1 ,sum2,sum;
       for(int S = 0;S < 1 << n2; ++S) {
          cnt = 0,sum1 = 0,sum2 = 0;
          for(int i = 0;i < n2;++i) {
              if(S >> i & 1) {
                  sum1 += vi[i];
                  cnt++;
              } else {
                  sum2 += wi[i];
              }
          }
          num[cnt].push_back(sum1 - sum2);
       }

       for(int i = 0;i < n2;++i) {
           sort(num[i].begin(),num[i].end());
           num[i].erase(unique(num[i].begin(),num[i].end()),num[i].end());
       }

       int ans = INF;
       for(int S = 0;S < 1 << (n-n2);++S) {
           sum,cnt = 0,sum1 = 0,sum2 = 0;
           for(int i = 0;i < (n-n2);++i) {
               if(S >> i & 1) {
                   sum1 += vi[i+n2];
                   cnt++;
               } else {
                   sum2 += wi[i+n2];
               }
           }
           int t = n - n2 - cnt;
           sum = sum1 - sum2;
           vector<int>::iterator iter;
           iter = lower_bound(num[t].begin(),num[t].end(),-sum);

           if(iter != num[t].end() && abs(*iter + sum) < ans)
               ans = abs(*iter + sum);

           if(iter != num[t].begin()) {
                --iter;
               if(abs(*iter + sum) < ans) ans = abs(*iter + sum);
           }
       }

        printf("%d\n",ans);
   }
   return 0;
}

/*

3
1 2 3
4 2 1

5
1 2 3 5 4
1 1 1 1 5

6
1 2 3 4 5 5
1 1 1 1 1 8

*/

版权声明:本文博客原创文章,博客,未经同意,不得转载。

时间: 2024-12-19 18:20:56

FZUOJ Problem 2178 礼品配送的相关文章

FZUOJ Problem 2178 礼物分配

Problem 2178 礼物分配 题目链接: Click Here~ Problem Description 在双胞胎兄弟Eric与R.W的生日会上,他们共收到了N个礼物,生日过后他们决定分配这N个礼物(numv+numw=N).对于每个礼物他们俩有着各自心中的价值vi和wi,他们要求各自分到的礼物数目|numv-numw|<=1,并且各自所衡量的礼物价值的差值|sumv-sumw|尽可能小,现在他们想知道最小的差值是多少.  Input 第一行为一个整数表示数据组数T. 接下来T组数组,每组

fzuoj Problem 2236 第十四个目标(树状数组+dp)

Problem 2236 第十四个目标  Problem Description 目暮警官.妃英里.阿笠博士等人接连遭到不明身份之人的暗算,柯南追踪伤害阿笠博士的凶手,根据几起案件现场留下的线索发现凶手按照扑克牌的顺序行凶.在经过一系列的推理后,柯南发现受害者的名字均包含扑克牌的数值,且扑克牌的大小是严格递增的,此外遇害者与毛利小五郎有关. 为了避免下一个遇害者的出现,柯南将可能遭到暗算的人中的数字按关联程度排列了出来,即顺序不可改变.柯南需要知道共有多少种可能结果,满足受害人名字出现的数字严格

fzuoj Problem 2179 chriswho

http://acm.fzu.edu.cn/problem.php?pid=2179 Problem 2179 chriswho Accept: 57    Submit: 136 Time Limit: 10000 mSec    Memory Limit : 327680 KB  Problem Description Chriswho很喜欢数字,特别喜欢一种数字,它能整除它的每一位数字(如果该位是0当做能整除),比如说126这个数字他就很喜欢,因为126%1=126%2=126%6=0.为

fzuoj Problem 2177 ytaaa

http://acm.fzu.edu.cn/problem.php?pid=2177 Problem 2177 ytaaa Accept: 113    Submit: 265Time Limit: 2000 mSec    Memory Limit : 32768 KB  Problem Description Ytaaa作为一名特工执行了无数困难的任务,这一次ytaaa收到命令,需要炸毁敌人的一个工厂,为此ytaaa需要制造一批炸弹以供使用. Ytaaa使用的这种新型炸弹由若干个炸药组成,每

fzuoj Problem 2129 子序列个数

http://acm.fzu.edu.cn/problem.php?pid=2129 Problem 2129 子序列个数 Accept: 162    Submit: 491Time Limit: 2000 mSec    Memory Limit : 32768 KB  Problem Description 子序列的定义:对于一个序列a=a[1],a[2],......a[n].则非空序列a'=a[p1],a[p2]......a[pm]为a的一个子序列,其中1<=p1<p2<..

FZUOJ Problem 2200 cleaning DP

Problem 2200 cleaning  Problem Description N个人围成一圈在讨论大扫除的事情,需要选出K个人.但是每个人与他距离为2的人存在矛盾,所以这K个人中任意两个人的距离不能为2,他们想知道共有多少种方法.  Input 第一行包含一个数T(T<=100),表示测试数据的个数. 接下来每行有两个数N,K,N表示人数,K表示需要的人数(1<=N<=1000,1<=K<=N).  Output 输出满足题意的方案数,方案数很大,所以请输出方案数mo

【BZOJ】【2178】圆的面积并

自适应辛普森积分 Orz Hzwer 辛普森真是个强大的东西……很多东西都能积= = 这题的正解看上去很鬼畜,至少我这种不会计算几何的渣渣是写不出来……(对圆的交点求图包,ans=凸包的面积+一堆弓形的面积,另外还有中空的情况……那种凸包怎么求啊喂!) 1 /************************************************************** 2 Problem: 2178 3 User: Tunix 4 Language: C++ 5 Result: A

Problem 2238 Daxia &amp; Wzc&#39;s problem 1627 瞬间移动

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1627 http://acm.fzu.edu.cn/problem.php?pid=2238 对应的51NOD这个题,先把n--和没m-- 再套公式 #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorit

ArcGIS空间分析工具

1. 3D分析 1.1. 3D Features toolset 工具 工具 描述 3D Features toolset (3D 要素工具集) Add Z Information 添加 Z 信息 添加关于具有 Z 值的要素类中的要素的高程属性的信息. Buffer 3D 3D 缓冲 围绕点或线创建三维缓冲区以生成球形或圆柱形的多面体要素. Difference 3D 3D 差异 消除目标要素类中部分与减法要素类中闭合的多面体要素体积重叠的多面体要素. Enclose Multipatch 封闭