SPOJ:Harbinger vs Sciencepal(分配问题&不错的DP&bitset优化)

Rainbow 6 is a very popular game in colleges. There are 2 teams, each having some members and the 2 teams play some matches against each other. The team which wins the maximum number of matches wins the game! Two of my friends Ashank and Aditya (better known as Harbinger and Sciencepal) are great gamers and they want to compete. So they decide to form their own teams.

There are 2*N players who are interested to be a part of their team. Each player has some rating (based on his performance) and Akarsh(Nimbus) is responsible for forming their teams. Being a good friend of both, he wants to form two teams such that the difference of total ratings of the players between the teams becomes minimum. The players come to him in pairs and he has to put one of them in Harbinger's team and the other in Sciencepal's team at that instant. This is a tedious task for him and therefore he needs your help!

Input

The first line of the input contains an integer T denoting the number of the test cases. (1 ≤ T ≤ 10)

First line of each test case contains a number N denoting the number of pair of players. (1 ≤ N ≤ 200)

Next N lines contains rating of the persons in pairs as x and y. (0 ≤ x , y ≤ 250)

Output

For each test case, print a single integer denoting the minimum possible absolute rating difference between Sciencepal's and Harbinger's team.

Example

Input:

1
2
2 3
4 5

Output:
0

题意:给定N对人,每对人,其中一个分给A班,另一个给B班。每个人都有自己的价值Xi,现在问如何分班使得两个班的价值差最小。(N<200;Xi<=2500;每个点有<=T=10组数据,时x限1s)

思路:每对的差值绝对值a,累加和为sum;即求最靠近sum/2的背包。用bitset优化一下。

#include<cstdio>
#include<cstdlib>
#include<bitset>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=5000010;
bitset<maxn>S;
int a[210];
int main()
{
    int T,N,ans,i,x,y;
    scanf("%d",&T);
    while(T--){
        S.reset(); ans=0;
        scanf("%d",&N);
        for(i=1;i<=N;i++){
            scanf("%d%d",&x,&y);
            a[i]=abs(x-y);
            ans+=a[i];
        }
        S[0]=1;
        for(i=1;i<=N;i++){
            S|=S<<a[i];
        }
        for(i=ans/2;i>=0;i--){
            if(S[i]==1){
    
                cout<<ans-i-i<<endl;
                break;
            }
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/hua-dong/p/8915858.html