Problem 2178 Gift Assignment
Topic Links: Click here~
Problem Description
At the birthday party of the twin brothers Eric and R.W, they received a total of n gifts, and after their birthdays they decided to assign the n gifts (numv+numw=n). For each gift they have the value of their hearts VI and WI, they asked their respective number of gifts |numv-numw|<=1, and the value of each of the values of the gift |sumv-sumw| as small as possible, now they want to know the minimum difference is how much. Input first behaves as an integer representing the number of data groups T. Next to the T array, the first behavior of each set of data is an integer n.
(n<=30) The second line has N integers, which represents the value of each gift measured by Eric. (1<=vi<=10000000) The third line also has n integers, which represent the value of each gift that R.W measures wi. (1<=wi<=10000000) Output for each set of data. Output the minimum difference.
Algorithmic analysis: The easiest way to think about it is to enumerate the violence directly. Now for the first person to analyze, each item has a choice or not to choose the possibility.
The general situation of such words is 2^30 the second party. Definitely timed out. Thinking about how to optimize.
Very easy to think of a two-point search. is binary find.
The idea is to preprocess the first half of the results first.
Then, use the previous results to infer the following situation. This can be optimized to the 2^15 of the second party.
#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;} /*31 2 34 2 151 2 3 5 41 1 1 1 561 2 3 4 5 51 1 1 1 1 8*/
Copyright notice: This article blog original articles, blogs, without consent, may not be reproduced.
Fzuoj Problem 2178 Gift delivery