SRM 582 Div II Level Three: ColorTheCells, Brute Force 算法

题目来源:http://community.topcoder.com/stat?c=problem_statement&pm=12581


Burte Force 算法,求解了所有了情况,注意 next_permutation 函数的用法。

#include <iostream>
#include <vector>
#include <limits>
#include <algorithm>

using namespace std;

class ColorTheCells
{
private:
	vector <int> dryingTime;	/* 需要干燥的时间  */
	vector <long> dryedTime;	/* 正好干燥的时间,0表示还没有paint */
	vector <int> paint_order;	/* paint格子的顺序 */
public:
	long calc(int seq);
	int minimalTime(vector <int> dryingTime);
};

#define MOVE_TIME 1L
#define PAINT_TIME 1L
#define INFINITY_TIME LONG_MAX 

/* 参考Ueddy代码实现 */
int ColorTheCells::minimalTime(vector<int> dryingTime)
{
	int num = dryingTime.size();
	long minTime = INFINITY_TIME;
	int i, j;

	this->dryingTime = dryingTime;
	paint_order.clear();		/* paint 的顺序 */
	dryedTime.clear();

	for (i = 0; i < num; i++) {
		paint_order.push_back(i);
		dryedTime.push_back(0);
	}

	/* brute force,枚举所有的情况,选出最小时间 */
	do {
		for (i = 0; i < (1<<num); i++) {
			for (j = 0; j < num; j++) {
				dryedTime[j] = 0;
			}
			minTime = min(minTime, calc(i));
		}
	} while (next_permutation(paint_order.begin(), paint_order.end()));

	return minTime;
}

/**
 * seq为一个序列,0表示在被paint位置左边paint, 1表示在右边paint,paint的顺序由
 * paint_order指定。
 */
long ColorTheCells::calc(int seq)
{
	long time;			/* 所用时间 */
	int num = dryingTime.size();
	int paint_dir;			/* paint方向,在被paint位置左边还是右边paint */
	int cur_pos;			/* 当前位置 */
	int paint_pos;			/* paint位置,不是被paint的位置 */
	int bias;			/* 从当前位置向左走还是向右走 */
	
	cur_pos = 0;
	time = 0;
	for (int i = 0; i < num; i++) {
		paint_dir = seq & 1;
		seq /= 2;
		paint_dir = paint_dir ? 1 : -1;
		paint_pos = paint_order[i] + paint_dir;
		if (paint_pos < 0 || paint_pos >= num) {	/* 位置不合法 */
			return INFINITY_TIME;
		}

		bias = 1;			/* 从当前位置向右走 */
		if (cur_pos - paint_pos > 0) {	/* 从当前位置向左走 */
			bias = -1;
		}
		
		/* 用for循环到达paint位置,中间遇到还没有干燥的格子要等待 */
		for (; cur_pos != paint_pos; cur_pos += bias) {
			if (dryedTime[cur_pos+bias] > time) {	/* 等待干燥 */
				time = dryedTime[cur_pos+bias];
			}
			time += MOVE_TIME;		/* 移动时间 */
		}
		time += PAINT_TIME;		/* 到达目的地,paint时间 */
		dryedTime[paint_order[i]] = time + dryingTime[paint_order[i]];	/* 更新该格子干燥时间  */
	}

	return time;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值