War

我之前对于dp的认识拘泥于三步的变化,

一个递归,一个二维的记忆表,以及由下而上求值填满整个矩阵。

得到矩阵右上角的值就是最后的结果。

这道题目我发现走不到第三步。因为他的记忆表实在没法总结成二维的形式。

二维记忆表有很多例子,比如矩阵相乘问题,01背包问题和生产线问题。

今天这个问题比较特殊,所以记录一下。顺便记录一下公司一个大牛的离职。


问题是这样的:

说有N个战士和M把武器,战士表示成(min,max)的值对,表示他能用的武器的最小和最大重量……(居然有最小重量只说)

然后武器列表是各个武器的重量。求最多能有几个匹配。

比如(1,5)(3,7)(5,10)三个战士,有三把武器『4,8,9』,最多只能武装2个人。


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Hashtable;
//zju 3508
//assume f(slist,wlist) can caaulate the max number with giving soliderList and weaponList
//then f(slist,wlist) = max{f(slist-one,wlist-one) + g(onesolider,oneweapon)}

public class war {
	public static void main(String[] args) {
		int soliderCount = 3;
		int weaponCount = 3;
		int[] minArray = {1, 3, 5};
		int[] maxArray = {5, 7, 10};
		int[] weaponArray = {4, 8, 9};
		war w = new war(soliderCount, weaponCount, minArray, maxArray,
				weaponArray);
		int maxSoliders = w.CaculateMaxSoliders();
		System.out.println(maxSoliders);
	}

	class solider {
		public solider(int max, int min) {
			this.max = max;
			this.min = min;
		}

		public int max = 0;
		public int min = 0;
	}

	Hashtable<String, Integer> HistoryNodes = new Hashtable<String, Integer>();

	public war(int soliderCount, int weaponCount, int[] min, int[] max,
			int[] weaponArray) {
		for (int i = 0; i < soliderCount; i++) {
			solider s = new solider(max[i], min[i]);
			this.soliderlist.add(s);
		}
		for (int i = 0; i < weaponCount; i++) {
			this.weaponList.add(weaponArray[i]);
		}
	}

	public ArrayList<solider> soliderlist = new ArrayList<solider>();
	public ArrayList<Integer> weaponList = new ArrayList<Integer>();

	public int CaculateMaxSoliders() {
		int maxSolider = GetMax(this.soliderlist, this.weaponList);
		return maxSolider;
	}

	private int GetMax(ArrayList<solider> soliderlist2,
			ArrayList<Integer> weaponList2) {
		int maxvalue = 0;
		String currentStatusKey = GenerateKey(soliderlist2, weaponList2);
		if (this.HistoryNodes.containsKey(currentStatusKey)) {
			return HistoryNodes.get(currentStatusKey);
		} else if (soliderlist2.size() == 1) {
			solider s = soliderlist2.get(0);
			for (int i = 0; i < weaponList2.size(); i++) {
				if (weaponList2.get(i) >= s.min && weaponList2.get(i) <= s.max)
					maxvalue = 1;
			}
			maxvalue = 0;
		} else if (weaponList2.size() == 1) {
			int w = weaponList2.get(0);
			for (int i = 0; i < soliderlist2.size(); i++) {
				if (w >= soliderlist2.get(i).min
						&& w <= soliderlist2.get(i).max)
					maxvalue = 1;
			}
			maxvalue = 0;
		} else {
			for (int removeSoliderIndex = 0; removeSoliderIndex < soliderlist2
					.size(); removeSoliderIndex++) {
				ArrayList<solider> subSoliderList = GetSubSoliderList(
						removeSoliderIndex, soliderlist2);
				for (int removeWeaponIndex = 0; removeWeaponIndex < weaponList2
						.size(); removeWeaponIndex++) {
					ArrayList<Integer> subWeaponList = GetSubWeaponList(
							removeWeaponIndex, weaponList2);
					int subvalue = GetMax(subSoliderList, subWeaponList);
					int totalvalue = subvalue
							+ GetMatch(soliderlist2.get(removeSoliderIndex),
									weaponList2.get(removeWeaponIndex));
					if (totalvalue > maxvalue)
						maxvalue = totalvalue;
				}
			}
		}
		this.HistoryNodes.put(currentStatusKey, maxvalue);
		return maxvalue;
	}

	private String GenerateKey(ArrayList<solider> soliderlist2,
			ArrayList<Integer> weaponList2) {
		String key = "";
		for (int i = 0; i < soliderlist2.size(); i++) {
			key += "m" + soliderlist2.get(i).min + "M"
					+ soliderlist2.get(i).max;
		}
		for (int i = 0; i < weaponList2.size(); i++) {
			key += "w" + weaponList2.get(i);
		}
		return key;
	}

	private int GetMatch(solider solider, Integer integer) {
		if (integer >= solider.min && integer <= solider.max)
			return 1;
		else
			return 0;
	}

	private ArrayList<Integer> GetSubWeaponList(int removeIndex,
			ArrayList<Integer> parentList) {
		ArrayList<Integer> subList = new ArrayList<Integer>();
		for (int i = 0; i < parentList.size(); i++) {
			if (i == removeIndex) {
				continue;
			} else {
				subList.add(parentList.get(i));
			}
		}
		return subList;
	}

	private ArrayList<solider> GetSubSoliderList(int removeIndex,
			ArrayList<solider> parentList) {
		ArrayList<solider> subList = new ArrayList<war.solider>();
		for (int i = 0; i < parentList.size(); i++) {
			if (i == removeIndex) {
				continue;
			} else {
				subList.add(parentList.get(i));
			}
		}
		return subList;
	}

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值