zoukankan      html  css  js  c++  java
  • 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];
    }
    
  • 相关阅读:
    AS/400开发经验点滴(三)如何使用分布式关系数据库
    AS/400开发经验点滴(五)通用日志管理工具
    AS/400开发经验点滴(二)一个批量修改文件属性的工具
    FTP执行AS400命令
    ORA12514 TNS 监听程序当前无法识别连接描述符中请求服务 的解决方法
    Centos 查看系统硬件信息
    [转]Oracle的DBMS_METADATA包
    java读写删.text,.xml文件内容
    oracle 是user_tables里面可以查找到一个表,而用DESC或者insert语句插入时就会报不存在视图。
    Oracle监听服务lsnrctl参数及查询状态详解
  • 原文地址:https://www.cnblogs.com/jolin123/p/3975231.html
Copyright © 2011-2022 走看看