POJ 2576 Tug of War 随机算法

原题地址:http://poj.org/problem?id=2576

Tug of War


Time Limit: 3000MS

 
Memory Limit: 65536K


Total Submissions: 8525

 
Accepted: 2320

Description

A tug of war is to be arranged at the local office picnic. For the tug of war, the picnickers must be divided into two teams. Each person must be on one team or the other; the number of people on the two teams must not differ by more than 1; the total weight of the people on each team should be as nearly equal as possible.

Input

The first line of input contains n the number of people at the picnic. n lines follow. The first line gives the weight of person 1; the second the weight of person 2; and so on. Each weight is an integer between 1 and 450. There are at most 100 people at the picnic.

Output

Your output will be a single line containing 2 numbers: the total weight of the people on one team, and the total weight of the people on the other team. If these numbers differ, give the lesser first.

Sample Input

3

100

90

200

Sample Output

190 200

题意:有n个人要分成两队进行拔河比赛,要求两队人数之差不超过1,且体重之和尽可能接近。

思路:先按体重从小到大排序,然后把前一半划为a队,后一半划为b队,算出体重之差作为当前最小值。生成两个随机数x,y,作为进行交换的队员编号,即把a队的x号队员放到b队,把b队的y号队员放到a队,检查交换后体重之差是否更小,若是则交换过来并记录新的最小值,否则不交换。重复操作N次,只要RP足够好即可AC。

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <stdlib.h>
 4 #include <time.h>
 5 using namespace std;
 6
 7 int main(void)
 8 {
 9     srand((unsigned)time(NULL));
10     int N, n, a[110], b[55], c[55], nb, nc, sumb, sumc, close, x, y, sx, sy;
11     while(~scanf("%d", &n))
12     {
13         for(int i=0; i<n; ++i)
14             scanf("%d", a+i);
15         if(n==1)
16         {
17             printf("0 %d\n", a[0]);
18             continue;
19         }
20         sort(a, a+n);
21         sumb = sumc = 0;
22         if(n&1)
23         {
24             nb = n/2+1;
25             nc = n - nb;
26             int i = 0;
27             for(; i<nb; ++i)
28                 b[i] = a[i], sumb += a[i];
29             for(; i<n; ++i)
30                 c[i-nb] = a[i], sumc += a[i];
31         }
32         else
33         {
34             nb = nc = n/2;
35             int i = 0;
36             for(; i<nb; ++i)
37                 b[i] = a[i], sumb += a[i];
38             for(; i<n; ++i)
39                 c[i-nb] = a[i], sumc += a[i];
40         }
41         close = abs(sumb-sumc);
42         N = 1000000;
43         while(N--)
44         {
45             x = rand() % nb;
46             y = rand() % nc;
47             sx = sumb - b[x] + c[y];
48             sy = sumc + b[x] - c[y];
49             if(abs(sx-sy) < close)
50             {
51                 sumb = sx;
52                 sumc = sy;
53                 b[x] ^= c[y], c[y] ^= b[x], b[x] ^= c[y];
54                 close = abs(sx-sy);
55             }
56         }
57         if(sumb > sumc)
58             sumb ^= sumc, sumc ^= sumb, sumb ^= sumc;
59         printf("%d %d\n", sumb, sumc);
60     }
61 }
时间: 2024-10-11 08:48:16

POJ 2576 Tug of War 随机算法的相关文章

随机算法 poj 2576 Tug of War

Tug of War Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 8187   Accepted: 2204 Description A tug of war is to be arranged at the local office picnic. For the tug of war, the picnickers must be divided into two teams. Each person must b

poj 2576 Tug of War

还是神奇的随机算法,,(看视频说这是爬山法??) 其实就是把序列随机分成两半(我太弱,只知道random_shuffle),然后再每个序列里rand一个位置,x,y然后比较是不是交换之后是更优的. 然后重复这个过程. 神奇.. 1 #include<cstdio> 2 #include<cstring> 3 #include<ctime> 4 #include<iostream> 5 #include<algorithm> 6 #define L

POJ 3318:Matrix Multiplication(随机算法)

http://poj.org/problem?id=3318 题意:问A和B两个矩阵相乘能否等于C. 思路:题目明确说出(n^3)的算法不能过,但是通过各种常数优化还是能过的. 这里的随机算法指的是随机枚举矩阵C的一个位置,然后通过A*B计算是否能够得到矩阵C相应位置的数,如果不等,就直接退出了,如果跑过一定的数量后能够相等,那么就可以判断这个矩阵C等于A*B的.第一次见这样的题目...有点新奇. 暴力算法: 1 #include <cstdio> 2 using namespace std;

poj 3114(korasaju算法和dij算法)

Countries in War Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2407   Accepted: 751 Description In the year 2050, after different attempts of the UN to maintain peace in the world, the third world war broke out. The importance of indus

Miller_Rabin算法(随机算法,判断一个数是否是素数)

1 const int S = 20;//随机算法判定次数,S越大,判错概率越小 2 LL pow_mod(LL a, LL b, LL mod) { // a^b%mod 3 LL ans = 1; 4 a = a % mod; 5 while(b) { 6 if(b & 1) { 7 ans = (ans * a) % mod; 8 } 9 a = ( a * a ) % mod; 10 b >>= 1; 11 } 12 return ans; 13 } 14 bool check

微信红包随机算法

最近看了一篇文章,讲微信红包随机算法的.感觉很不错,所以自己实现了下,并进行了简单测试. 算法 算法很简单,不是提前算好,而是抢红包时计算: 红包里的金额怎么算?为什么出现各个红包金额相差很大?答:随机,额度在0.01和剩余平均值*2之间. 实现 实现上述算法的逻辑主要是: public static double getRandomMoney(RedPackage _redPackage) { // remainSize 剩余的红包数量 // remainMoney 剩余的钱 if (_red

加权随机算法

加权随机算法一般应用在以下场景:有一个集合S,里面比如有A,B,C,D这四项.这时我们想随机从中抽取一项,但是抽取的概率不同,比如我们希望抽到A的概率是50%,抽到B和C的概率是20%,D的概率是10%.一般来说,我们可以给各项附一个权重,抽取的概率正比于这个权重.那么上述集合就成了: {A:5,B:2,C:2,D:1} 方法一: 扩展这个集合,使每一项出现的次数与其权重正相关.在上述例子这个集合扩展成:{A,A,A,A,A,B,B,C,C,D}然后就可以用均匀随机算法来从中选取. 好处:选取的

权重随机算法的java实现

一.概述 平时,经常会遇到权重随机算法,从不同权重的N个元素中随机选择一个,并使得总体选择结果是按照权重分布的.如广告投放.负载均衡等. 如有4个元素A.B.C.D,权重分别为1.2.3.4,随机结果中A:B:C:D的比例要为1:2:3:4. 总体思路:累加每个元素的权重A(1)-B(3)-C(6)-D(10),则4个元素的的权重管辖区间分别为[0,1).[1,3).[3,6).[6,10).然后随机出一个[0,10)之间的随机数.落在哪个区间,则该区间之后的元素即为按权重命中的元素. 实现方法

随机算法 - HNU 13348 Finding Lines

Finding Lines Problem's Link: http://acm.hnu.cn/online/?action=problem&type=show&id=13348&courseid=0 Mean: 给你平面上1e5个点,让你判断是否可以找到一条直线,使得p%的点都在这条直线上. analyse: 经典的随机算法题. 每次随机出两个点,然后对n个点进行判断,看是否有p%的点在这条直线上. 关于随机算法正确性的证明: 每次随机一个点,这个点在直线上的概率是p,p最小为2