zuo-algorithm-greedy algorithm

Example 8:
insert image description hereinsert image description hereThe initial capital is 1, and a maximum of 4 projects can be done. How to arrange it to maximize the final profit

insert image description hereMethod: Create a small root pile according to the cost, put all the items into the small root pile (these are called locked projects); the initial fund is 1, pop the projects with the initial capital <= 1 into the big root pile (established according to the profit), that is, pop up (1,1) and (1,4) ((these are called unlocking items)), then (1,4) is on top of (1,1), and (1,4) pops up in the big root pile, and the initial funds are now Change to 5, and then pop out the projects with initial funds <= 5 in the small root pile and put them into the big root pile.
insert image description here

public class CostProfix {
    
    
	public static class Node{
    
    
		public int profit;
		public int cost;
		public Node(int p,int c) {
    
    
			this.profit=p;
			this.cost=c;
		}
		
	}
	public static class MinCostComparator implements Comparator<Node>{
    
    
		//按照花费组织的小根堆的比较器
		@Override
		public int compare(Node o1, Node o2) {
    
    
			// TODO 自动生成的方法存根
			return o1.cost-o2.cost;
		}
		
	} 
	public static class MaxProfitComparator implements Comparator<Node>{
    
    
		//按照利润组织的啊大根堆的比较器
		@Override
		public int compare(Node o1, Node o2) {
    
    
			// TODO 自动生成的方法存根
			return o2.profit-o1.profit;
		}
		
	}
	//k指最多串行做k个项目,m表示初始资金,最终输出获得的最大钱数
	public static int findMaxMoney(int k,int m,int[] profits,int[] costs) {
    
    
		PriorityQueue<Node> minCostQ=new PriorityQueue<>(new MinCostComparator());
		PriorityQueue<Node> maxProfitQ=new PriorityQueue<>(new MaxProfitComparator() );
		//把所有项目扔到小根堆里去,按照花费组织的
		for(int i=0;i<profits.length;i++) {
    
    
			minCostQ.add(new Node(profits[i],costs[i]));
		}
		//进行K轮,因为最多串行k个项目
		for(int i=0;i<k;i++) {
    
    
			//能力所及的项目,全解锁
			while(!minCostQ.isEmpty()&&minCostQ.peek().cost<=m) {
    
    
				maxProfitQ.add(minCostQ.poll());
			}
			if(maxProfitQ.isEmpty()) {
    
    
				return m;
			}
			m+=maxProfitQ.poll().profit;
		}
		return m;
		
	}
	public static void main(String[] args) {
    
    
		int k=4;
		int m=1;
		int[] costs= {
    
    1,1,2,2,3,4};
		int[] profits= {
    
    1,4,3,7,2,10};
		int maxmoney=findMaxMoney(k,m,profits,costs);
		System.out.println(maxmoney);
	}
}

operation result
insert image description here

insert image description here
This is also an example method of combining large root piles and small root piles
: (1) If the given number is smaller than the top of the big root pile, enter the large root pile; if not, enter the small root pile (2) Compare the size of the large root pile and the small root pile Size, if the difference is equal to 2, pop the top of the heap with the larger size into the heap with the smaller size.
insert image description hereIn this case, the smaller n/2 numbers are placed in the large root pile, and the larger n/2 numbers are placed in the small root pile

n queen problem
insert image description here

/*n皇后问题*/
public class NHuangHou {
    
    
	public static int num1(int n) {
    
    
		if(n<1) {
    
    
			return 0;
		}
		int[] record=new int[n];//record[i]表示i行的皇后放在了第几列
		return process(0,record,n);
	}
	//i表示目前来到了第i行
	//record【0...i-1】表示之前的行,放的皇后位置(任何两个皇后一定不工共行不共列不共斜线)
	//n表示整体一共有多少行
	//返回值是,摆完所有的皇后,合理的摆法有多少种
	public static int process(int i, int[] record, int n) {
    
    
		if(i==n) {
    
    //终止行
			return 1;
		}
		int res=0;
		for(int j=0;j<n;j++) {
    
    //当前行在i行,尝试i行所有列
			//当前i行的皇后,放在j列,会不会和之前(0...i-1)的皇后,共行共列或共斜线
			//如果是,认为有效
			//如果不是,认为无效
			if(isValid(record,i,j)) {
    
    //之前放的所有皇后,都不要与i行j列的皇后冲突
				record[i]=j;//如果都不冲突,才能放
				res+=process(i+1,record,n);//然后去i+1行放皇后
			}
			//System.out.print(res+" ");//测试
		}
		//System.out.print(res+" ");//测试
		return res;
	}
	//record【0...i-1】需要看,record【i...】不需要看
	//返回i行皇后,放在j列,是否有效
	public static boolean isValid(int[] record, int i, int j) {
    
    
		for(int k=0;k<i;k++) {
    
    //之前某个K行的皇后
			if(j==record[k]||Math.abs(record[k]-j)==Math.abs(i-k)) {
    
    
	//j==record[k]检查是否共列,Math.abs(record[k]-j)==Math.abs(i-k)检查是否共行(列坐标的绝对值是否等于行坐标的绝对值)
				return false;
			}
			
		}
		return true;
	}
	public static void main(String[] args) {
    
    
		int result=num1(5);
		System.out.println(result);
	}
}

Guess you like

Origin blog.csdn.net/qq_42373007/article/details/123950716
Recommended