Sicily 1176. Two Ends 解题报告

1176_Two_Ends

 

题目链接:

http://soj.me/1176

 

题目大意:

很简单的一道题目,甲乙从卡片堆中轮流拿卡片,要使甲得到的卡片数字和最大,求这时甲乙数字和的差.两个人每次只能拿卡片队列中最左边或者最右边的一张,而乙每次已经设定好都会拿左右两张中比较大那张(相同的话拿左边的).说白就是求一个使甲能拿到最大数字和的策略

 

思路:

假设卡片序号为0到n - 1,(a,b)表示从序号a到b的卡片中甲能拿到的最大和,要求的(a,b),需要首先求出(a,b - 2),(a + 1, b - 1)和(a + 2, b),在这三种情况中甲乙各再取一张卡片,哪种使得甲的和最大的话结果就是哪个.一开始使用递归的方法超时了,因为整个过程中确实进行了很多重复的计算,所以增加了数组record[][]来记录产生的过程结果,避免重复计算,其实就是动态规划中带记录的自顶向下的方法.

 

代码:

#include <iostream>
#include <memory.h>
using namespace std;


int record[1001][1001];//用来记录递归过程产生的结果,避免重复的计算节省时间

int get_best_points_recursive(int *cards, int left_index, int right_index);

int main() {
	int n, count = 1;
	while (cin >> n && n != 0) {
		memset(record, 0, sizeof(record));
		int cards[n], total_points = 0;
		for (int i = 0; i < n; ++i) {
			cin >> cards[i];
			total_points += cards[i];
		}

		int best_points = get_best_points_recursive(cards, 0, n - 1);

		cout << "In game " << count
				<< ", the greedy strategy might lose by as many as "
				<< best_points - (total_points - best_points) << " points."
				<< endl;
		count++;
	}
	return 0;
}

int get_best_points_recursive(int *cards, int left_index, int right_index) {
	if (record[left_index][right_index] == 0) {//这个区间的结果没计算过需要计算并将结果存到record中
		if (right_index - left_index == 1) {
			record[left_index][right_index] = max(cards[left_index],
					cards[right_index]);
		} else {
			int left_max, right_max; //先取左边一张的最大和和先取右边一张的最大和
			if (cards[left_index + 1] >= cards[right_index]) { //对手在剩下的卡片中拿左边的那张
				left_max = cards[left_index]
						+ get_best_points_recursive(cards, left_index + 2,
								right_index);
			} else {
				left_max = cards[left_index]
						+ get_best_points_recursive(cards, left_index + 1,
								right_index - 1);
			}
			if (cards[left_index] >= cards[right_index - 1])
				right_max = cards[right_index]
						+ get_best_points_recursive(cards, left_index + 1,
								right_index - 1);
			else
				right_max = cards[right_index]
						+ get_best_points_recursive(cards, left_index,
								right_index - 2);
			record[left_index][right_index] = max(left_max, right_max);
		}
	}
	return record[left_index][right_index];
}
posted @ 2014-09-16 16:39  Jolin123  阅读(319)  评论(0编辑  收藏  举报