poj1015

//============================================================================
// Name        : 1015.cpp
// Author      : 
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <stdio.h>
#include <cstring>
#include <algorithm>

#define	MAX_M 20
#define MAX_N 200
#define VALUE_ADD 21
#define MAX_VALUE 41
#define MAX_SUM_VALUE (MAX_M*MAX_VALUE)

using namespace std;

int m, n;

typedef struct data {
	int minus;
	int sum;
} Data;

Data d[MAX_N + 1];

typedef struct result {
	int f;
	struct result * last;
	int index;
	int ok;
} Result;

Result res[MAX_N + 1][MAX_M + 1][MAX_SUM_VALUE + 1];
int minus, sum;
Result * final;

void output(Result * r) {
	if (r) {
		output(r->last);
		if (r->index) {
			printf(" %d", r->index);
		}
	}
}

int main() {
	int jury = 0;
	while (scanf("%d %d", &n, &m)) {
		if (n == 0) {
			break;
		}
		jury++;
		for (int i = 1; i <= n; i++) {
			int sd, sp;
			scanf("%d %d", &sd, &sp);
			d[i].minus = sd - sp + VALUE_ADD;
			d[i].sum = sd + sp;
		}

		memset(res, 0, sizeof(res));
		res[0][0][0].ok = 1;
		for (int i = 1; i <= n; i++) {
			int ms = min(i, m);
			res[i][0][0].ok = 1;
			for (int j = 1; j <= ms; j++) {
				int max_sum = j * MAX_VALUE;
				int mid_sum = min(d[i].minus, max_sum);
				for (int k = 0; k < mid_sum; k++) {
					res[i][j][k] = res[i - 1][j][k];
					res[i][j][k].last = &res[i - 1][j][k];
					res[i][j][k].index = 0;
				}
				for (int k = d[i].minus; k <= max_sum; k++) {
					res[i][j][k] = res[i - 1][j][k];
					res[i][j][k].last = &res[i - 1][j][k];
					res[i][j][k].index = 0;

					Result& rn = res[i - 1][j - 1][k - d[i].minus];
					if (rn.ok) {
						if (rn.f + d[i].sum >= res[i][j][k].f) {
							res[i][j][k].ok = 1;
							res[i][j][k].f = rn.f + d[i].sum;
							res[i][j][k].last = &rn;
							res[i][j][k].index = i;
						}
					}
				}
			}
		}

		int mid = m * VALUE_ADD;
		sum = -1;
		for (int i = 0; i <= mid; i++) {
			int l = mid - i;
			int r = mid + i;
			if (res[n][m][l].ok) {
				minus = -i;
				sum = res[n][m][l].f;
				final = &res[n][m][l];
			}
			if (res[n][m][r].ok && res[n][m][r].f > sum) {
				minus = i;
				sum = res[n][m][r].f;
				final = &res[n][m][r];
			}
			if (sum >= 0)
				break;
		}

		int a = (minus + sum) / 2;
		int b = sum - a;
		printf(
				"Jury #%d\nBest jury has value %d for prosecution and value %d for defence:\n",
				jury, a, b);
		output(final);
		puts("\n");
	}

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值