2971--"mock test" birthday present Description a pair of twin siblings on the same day birthday, this day, their friends sent them a gift, each gift is 2 books, one to his brother, one to his sister, but did not say which is for the sister, which is to the brother, Each book has its own value, in order to avoid conflict, let you assign, ask the two people to obtain the value of the book and the gap between as small as possible. For example, there are 4 gifts: (3,5), (7,11), (8,8), (2,9), can assign 3,7,8,2 to sister, the rest of the elder brother, the value of the difference is: 5+11+8+9-3-7-8-2=13, if the 3,7,8,9 to sister, the rest of the elder brother, the value of the difference is: 3+ 7+8+9-5-11-8-2=1, this is the best solution. Input input file The first line of gift.in contains a positive integer n, representing the number of gifts, followed by n rows, two integers per line, representing the value of two books per gift (value range between 1 and 300). Output file Gift.out contains a non-negative integer representing the minimum value difference. Sample Input 4 3 5 7 8 8 2 9 Sample Output 1 Hint "Data scale" for 20% of the data, there are n≤20, for 40% of the data, there are n≤50, for 100% of the data, there are n≤150.
The positive solution to this problem is DP, but for this kind of problem, we can do it with randomization. DP is the delt of each group's birthday present, so we can write it in a thought that is approximate to 01 Knapsack is based on greedy adjustment (in fact, I think it can only be called random, no), every time to adjust all the order, and then do the greedy, will be large to the current small, will be small to the current large.
Want to see a random look at this article of mine
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <ctime>
#include <cstdlib>
using namespace std;
struct node{int l,r;
} W[150];
int n;
void Wash ()
{for
(int i=1;i<=n;i++)
{
int t=rand ()%n+1;
Swap (W[I].L,W[T].L);
Swap (W[I].R,W[T].R);
}
}
void Solve ()
{
int ti=1000;
int ans=0x3fffffff;
while (ti--)
{
wash ();
int sum1=0,sum2=0;
for (int i=1;i<=n;i++)
{
if (sum1<sum2) Sum1+=max (W[I].L,W[I].R), Sum2+=min (W[I].L,W[I].R);
else Sum2+=max (W[I].L,W[I].R), Sum1+=min (W[I].L,W[I].R);
} cout<< "dhasj\n";
Ans=min (Ans,abs (sum1-sum2));
}
cout<<ans;
}
int main () {
Srand (Time (NULL));
cin>>n;
for (int i=1;i<=n;i++)
cin>>w[i].l>>w[i].r;
Solve ();
return 0;
}
The following DP code comes from the network, lazy to write
var
a:array[0..151,1..2] of Longint;
Z:ARRAY[0..151] of Longint;
F:ARRAY[0..450000] of Longint;
I,j,v,h,k,n,min,m:longint;
Begin
READLN (n);
For I:=1 to n do begin
Readln (a[i,1],a[i,2]);
Z[i]:=abs (a[i,1]-a[i,2]);
H:=h+z[i];
End;
V:=h Div 2;
Fillchar (F,sizeof (f), 0);
For I:=1 to n does begin for
j:=v Downto z[i] Do begin
if F[J-Z[I]]+Z[I]>F[J] then f[j]:=f[j-z[i]]+z[i];
End;
End;
Writeln (ABS (H-f[v])-f[v]);
End.