• 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];
    }
    
  • 相关阅读:
    Tool工具页面代码
    Tool工具生成代码数据库Model生成代码
    类别切换 分页
    ASP.NET AJAX无刷新验证用户名
    VSS的配置和使用
    js 常用方法大全
    灵异——1995年北京330路公交车失踪案
    C#用HttpWebRequest通过代理服务器验证后抓取网页内容 。。。。。
    win2003远程 客户端无法连接到远程计算机。
    .net中点击button按钮显示下一条记录(上一条 下一条)
  • 原文地址:https://www.cnblogs.com/jolin123/p/3975231.html
Copyright © 2020-2023  润新知