您的位置:首页 > 其它

JOJ 1903 1129 1157 1278

2009-04-24 15:05 281 查看
JOJ 1903 Tug of War: http://acm.jlu.edu.cn/joj/showproblem.php?pid=1903
题目概述:给N个正整数,每个正整数在1到450之间,N最大是100,要求把N个正整数分成两组,两个分组包含的正整数的数目之差不能超过1,并且使得两个分组所含的正整数的和最接近。比如三个正整数100,90,200,显然分成{100,90}和{200},这时两组数和的差达到最小,为10。

这个题目在《编程之美》的数组分割问题中给出了三种分析和实现,第一种方法是随机交换,但有可能得到错误的解,第二种是类似背包问题的动态规划,时间复杂度2的N次方,第三种是根据结果分类,时间复杂度为O(sum * N),sum是这N个数的和。详见:http://blog.csdn.net/jcwKyl/archive/2009/02/23/3926444.aspx。这个题目的时限为15秒,第二种解法代码提交为3秒,第三种解法提交为1秒。各OJ上有大量0.00S的成绩,后来发现0.00S的成绩用的是随机交换。

JOJ 1129 Divisibility: http://acm.jlu.edu.cn/joj/showproblem.php?pid=1129
题目概述:输入N个整数(每个整数绝对值不超过10000)和一个正整数K(2<=K<=100),可以在两个整数间放置加号或减号。问是不是存在一种放置加减号的方法,使得N个整数的运算结果能被K整除。

这个题可以模仿《编程之美》在“数组分割”问题中使用的方法三的思路,被K整除的意思就是模K的结果为0,根据模K的结果将每次得到的中间结果分类,假设S(i)表示当前i个整数的任意加减组合所得到的所有结果,这些全部结果根据模K的余数最多有K类。当处理第i+1个整数a[i+1]时,有S(i+1)
= { (x + a[i+1]) mod k | x belongs to S(i) }。这样,可以在O(N*K)的时间复杂度内得出结果。代码如下:

#include <stdio.h>

#include <string.h>

int main() {

int i, j, t, kase,
n, k, ti;

char flag1[128], flag2[128], *pre, *cur, *tmp;

scanf("%d", &kase);

while(kase--) {

scanf("%d%d", &n, &k);

memset(flag1, 0, sizeof(flag1));

memset(flag2, 0, sizeof(flag2));

scanf("%d", &t);

cur
= flag1;

pre
= flag2;

t
%= k;

if(t < 0) t += k;

cur[t]
= 1;

for(i = 0; i < n - 1; i++) {

scanf("%d", &t);

for(j = 0; j < k;
j++) {

if(cur[j]) {

ti = (j + t) % k;

if(ti < 0) ti += k;

pre[ti] = 1;

ti = (j - t) % k;

if(ti < 0) ti += k;

pre[ti] = 1;

cur[j] = 0;

}

}

tmp = cur;

cur = pre;

pre = tmp;

}

printf("%s/n", cur[0]?"Divisible":"Not divisible");

}

}

JOJ 1157 Station Balance: http://acm.jlu.edu.cn/joj/showproblem.php?pid=1157

题目概述:有C个盒子和N个小球(N
<=2*C),每个盒子可以放0个、1个或2个小球。设N个小球的重量分别为M1,
M2, …, Mn。把N个小球放到C个盒子里,使每个盒子中放的小球的重量尽可能平均。设Ave表示每个盒子应该放的小球的重量,即Ave = (M1 + M2 + … + Mn) / C。题目的要求就是使下面的式子取值最小:SUM( | CMi – Ave | ),i = 1, 2, … ,
C。CMi表示第i个盒子中放的球的总重量。

题目中的C不大于5。但这个题目可以用贪心:将N个小球被上2*C-N个重量为0的小球,现在得到了2*C个重量,假设这2*C个重量从小到大排序为:M1,
M2, …, M2c。贪心策略就是开头取一个末尾取一个放到一个盒子里,如上即将M1和M2c放在第一个盒子里,将M2和M2c-1放到第二个盒子里,如此类推。

贪心证明:证明在最优解中,M1和M2c放在同一个盒子里。假设T是这个问题的一个最优解,如果T中某个盒子里放的是M1和M2c,则已证。否则,假设T中有两个盒子,分别放着小球(M1,
Mi), (Mj, M2c)。设这两个盒子的部分和为sum2:



JOJ 1278 Simply Subsets: http://acm.jlu.edu.cn/joj/showproblem.php?pid=1278

输入两个集合的元素,判断两个集合的包含、相等、相交关系。输入数据时,一行中有所有的一个集合的元素,使用getline和istringstream非常方便。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: