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

9 篇文章 0 订阅
4 篇文章 0 订阅

题目链接:https://vjudge.net/problem/SPOJ-R6PL

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<=250;每个点有<=T=10组数据,时x限1s)

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

#include <bits/stdc++.h>

using namespace std;

const int maxn = 500 * 202;

bitset<maxn>dp;
int main()
{
    int T;
    scanf("%d", &T);
    while(T --) {
        int n;
        scanf("%d", &n);
        dp.reset();
        dp[0] = 1;
        int s = 0;
        for(int i = 1;i <= n;i ++) {
            int in1, in2;
            scanf("%d %d", &in1, &in2);
            in1 = abs(in1-in2);
            s += in1;
            dp |= dp<<s;
        }
        for(int i = s / 2;i <= s;i ++) {
            if(dp[i]) {
                printf("%d\n", abs(s-2*i) );
                break;
            }
        }
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值