JAVA:尝试模型2:范围模型-纸牌总分问题(暴力递归-到-动态规划)

				//尝试模型2:范围模型
										//纸牌总分---动态规划
/*
提要:给定一个整形数组arr,代表数值不同的纸牌,
条件:玩家A、B每次依次拿走一张(A先拿),每次只能从最左、最右拿一张
要求:假设A、B都很聪明理智,返回最后获胜者的分数
*/

public static void main(String[] args) {
	int[] arr = {6,6,7,2,8,8,2,5,4,5,7,5,7,1,7,1,1,2,6,8,2,9,2,7,6,8,9,6,6,3,4,5,8,6,7,1,1,2,4,5,1,6,5};
	
	long start1 = System.currentTimeMillis();			    //System.currentTimeMillis()  测试系统运行时间
	System.out.println(cardViolence(arr));					//调用暴力递归
	long end1 = System.currentTimeMillis();
	System.out.println("cosr time1:"+(end1-start1)+" ms");
	/*									时间复杂度
	107 									2^n
	cosr time1:25923 ms
	测试结果:数据一样,但动态规划运行快很多倍
	107									n*logn
	cosr time2:1 ms
	 */
	
	long start2 = System.currentTimeMillis();
	System.out.println(cardDynamic(arr));					//调用动态规划
	long end2 = System.currentTimeMillis();
	System.out.println("cosr time2:"+(end2-start2)+" ms");

}


								//暴力递归
public static int cardViolence(int[] arr) {
	if(arr.length==0) {											//数组不为空
		return -1;
	}
	return Math.max(A(arr,0,arr.length-1),B(arr,0,arr.length-1));				//求最大值
}
public static int A(int[] arr,int l,int r) {				
	if( l<0 || r>arr.length) {													//出现不可能出现的情况,直接退出
		return -1;
	}
	if(l == r) {
		return arr[l];															//最后一个元素,直接输出
	}	
	return Math.max(arr[l]+B(arr,l+1,r), arr[r]+B(arr,l,r-1));					//找最左、最右 二种选择的最大值
}
public static int B(int[] arr,int l,int r) {
	if(l>r) {
		return -1;
	}
	if(l == r) {
		return 0;
	}
	return Math.min(A(arr,l+1,r), A(arr,l,r-1));								//同时找后手的最小值
}


									//动态规划
public static int cardDynamic(int[] arr) {
	if(arr.length==0 || arr==null) {
		return 0;
	}
	int[][] dp = new int[arr.length][arr.length];  								//记录A、B每次的值
	int[][] pd = new int[arr.length][arr.length]; 
	
	for(int k=0;k<arr.length;k++) {												//对应A中 l==r(输出 arr[l])
		dp[k][k]=arr[k];														//在A图中,对角线值已赋,B图中对角线为0=初始化也为0
	}
	for(int i=1;i<arr.length;i++) {
		int l = 0;																//A图中,将每个对角的空间(l,r)都遍历
		int r = i;
		while(l<arr.length && r<arr.length) {
			dp[l][r] = Math.max(arr[l]+pd[l+1][r], arr[r]+pd[l][r-1]);
			//就是: return Math.max(arr[l]+B(arr,l+1,r), arr[r]+B(arr,l,r-1));	
			pd[l][r] = Math.min(dp[l+1][r], dp[l][r-1]);
			//就是: return Math.min(A(arr,l+1,r), A(arr,l,r-1));	
			l++;
			r++;
		}
	}
	return Math.max(dp[0][arr.length-1], pd[0][arr.length-1]);					//对应最终 求最大值
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值