分配问题
分配问题
Description
对给定的n个任务与n个人之间的成本矩阵完成成本最低的任务分配策略。
Input
输入:第一行为用例个数,之后为每一个用例;用例的第一行为任务个数,即n;
用例的第二行为使用逗号隔开的人员完成任务的成本;每一个成本描述包括人员序号、任务序号和成本,使用空格隔开。人员序号和任务序号都是从1到n的整数,序号出现的次序没有固定规则。
Output
输出:每一个用例输出一行,从序号为1的人员开始,给出其分配的任务序号,使用空格隔开;使
用逗号将多个解隔开。结果按照人员分配的任务序号大小排,第一个人员的任务序号大的放在前面,如果相同则看第二个人员的任务,以此类推。
Sample Input 1
1
4
2 1 6,1 2 2,1 3 7,1 4 8,1 1 9,2 2 4,2 3 3,2 4 7,3 1 5,3 2 8,3 3 1,3 4 8,4 1 7,4 2 6,4 3 9,4 4 4
Sample Output 1
2 1 3 4
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
static Scanner scanner=new Scanner(System.in);
static int [][] personTask;//人员任务矩阵
static int n;//人员个数=任务个数=n
static List<Integer> res;
static int time;//最短时间
static boolean[] isDistrubuted;//已经分配的任务
public static void main(String[] args){
int T=scanner.nextInt();
while(T-->0){
n=scanner.nextInt();
scanner.nextLine();
personTask=new int[n][n];
res=new ArrayList<>();
time=Integer.MAX_VALUE;
String s[]=scanner.nextLine().split(",");
isDistrubuted=new boolean[n];
for(int i=0;i<s.length;i++){
String ss[]=s[i].split(" ");
int p=Integer.parseInt(ss[0])-1;
int t=Integer.parseInt(ss[1])-1;
int time=Integer.parseInt(ss[2]);
personTask[p][t]=time;
}
distribute(0,0,new ArrayList<>());
for(int i=0;i<n;i++){
System.out.print(res.get(i));
if(i!=n-1){
System.out.print(" ");
}
}
System.out.println("");
}
}
/**
*
* @param cur 递归参数 为第cur个人分配任务
*/
static void distribute(int cur, int currentTime,List<Integer> path){
if(cur==n) {
if(currentTime<time){
time=currentTime;
res=new ArrayList<>(path);
}
return;
}
//遍历任务
for(int i=0;i<n;i++){
if(isDistrubuted[i]) continue;
//分配
isDistrubuted[i]=true;
path.add((i+1));
currentTime+=personTask[cur][i];
distribute(cur+1,currentTime,path);
//回溯
isDistrubuted[i]=false;
currentTime-=personTask[cur][i];
path.remove((Integer)(i+1));
}
}
}
和为定值的子数组
Description
Given an array A of size N, find all combination of four elements in the array whose sum is equal to a given value K. For example, if the given array is {10, 2, 3, 4, 5, 9, 7, 8} and K = 23, one of the quadruple is “3 5 7 8” (3 + 5 + 7 + 8 = 23).
Input
The first line of input contains an integer T denoting the no of test cases. Then T test cases follow. Each test case contains two lines. The first line of input contains two integers N and K. Then in the next line are N space separated values of the array.(1<=T<=100;1<=N<=100;-1000<=K<=1000;-100<=A[]<=100)
Output
For each test case in a new line print all the quadruples present in the array separated by space which sums up to value of K. Each quadruple is unique which are separated by a delimeter “$” and are in increasing order.
Sample Input 1
2
5 3
0 0 2 1 1
7 23
10 2 3 4 5 7 8
Sample Output 1
0 0 1 2 $
2 3 8 10 $2 4 7 10 $3 5 7 8 $
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
/**
* 求数组的子数组,且四个元素子数组满足元素和为K 并且要去掉重复的数组
* 输入:T
* N K
* 数组元素
* 输出 子数组 子数组之间以$分割
*
* Sample Input 1
* 2
* 5 3
* 0 0 2 1 1
* 7 23
* 10 2 3 4 5 7 8
*
* Sample Output 1
* 0 0 1 2 $
* 2 3 8 10 $2 4 7 10 $3 5 7 8 $
*/
public class Main {
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
int T=sc.nextInt();
for(int t=0;t<T;t++) {
int n = sc.nextInt();
int k = sc.nextInt();
int arr[] = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
}
//调用方法
Arrays.sort(arr);//将数组进行排序
List<List<Integer>> res = new ArrayList<List<Integer>>();
List<Integer> l = new ArrayList<Integer>();
int sum = 0;
boolean[] used = new boolean[arr.length];
getSubArrayK(res, l, k, sum, arr, used);
for (int i = 0; i < res.size(); i++) {
for (int j = 0; j < res.get(i).size(); j++) {
System.out.print(res.get(i).get(j) + " ");
}
System.out.print("$");
}
System.out.println(" ");
}
}
private static void getSubArrayK(List<List<Integer>> list, List<Integer> l, int target, int sum, int[] candidates,boolean[] used){
if(sum==target){
list.add(l);
}
//如果元素不能到达四个元素则break
for(int i=0;i<candidates.length;i++){
if(l.size()+candidates.length-i<4)
break;
if(sum+candidates[i]>target){
break;
}
if (i > 0 && candidates[i] == candidates[i - 1] && !used[i - 1]) {
continue;
}
if(l.size()>0&&l.get(l.size()-1)>candidates[i]){
continue;
}
if(!used[i]){
List<Integer> newL =new ArrayList<Integer>(l);
newL.add(candidates[i]);
boolean[] newUsed = new boolean[used.length];
System.arraycopy(used, 0, newUsed, 0,used.length);
newUsed[i] = true;
getSubArrayK(list,newL,target,sum+candidates[i],candidates, newUsed);
}
}
}
}
拓扑排序的个数
import java.util.*;
/**
* @CreateDate 20210301
* @author zhengjiao
* @desciption 拓扑排序的个数
*/
public class Main {
static Scanner in=new Scanner(System.in);
static List<Edge> edges=new ArrayList<>();
static Set<Character> vs=new HashSet<>();//点的集合
static Map<Character,Integer> inDegree=new LinkedHashMap<>();//点的入度。
static int n=0;
static int ans=0;
static class Edge {
char start;
char end;
public Edge(char start, char end) {
this.start = start;
this.end = end;
}
// 重写hashcode方法
@Override
public int hashCode() {
int result = start;
result = 17 * result + end;
return result;
}
// 重写equals方法
@Override
public boolean equals(Object obj) {
if(!(obj instanceof Edge)) {
return false;
}
Edge edge = (Edge) obj;
if (this == edge) {
return true;
}
if (edge.start==this.start && edge.end==this.end) {
return true;
} else {
return false;
}
}
@Override
public String toString() {
return "Edge{" +
"start=" + start +
", end=" + end +
'}';
}
}
static void topoSort(int cnt){
if(cnt>=n){
ans++;
return;
}
for(Map.Entry<Character,Integer> entry:inDegree.entrySet()){
if(entry.getValue()!=0) continue;
//取入度为0的点
char v=entry.getKey();
inDegree.put(v,-1);//去掉该点
List<Character> justEdge=new ArrayList<>();//记录刚刚删除的边的集合
for(int i=0;i<edges.size();i++){
Edge edge=edges.get(i);
if(edge.start==v){
// 入度减1
inDegree.put(edge.end,inDegree.get(edge.end)-1);
//删除边
justEdge.add(edge.end);
edges.remove(edge);
}
}
topoSort(cnt+1);
//回溯)
inDegree.put(v,0);
for(int i=0;i<justEdge.size();i++){
char end=justEdge.get(i);
//添加边
edges.add(new Edge(v,end));
//入度加一
inDegree.put(end,inDegree.get(end)+1);
}
}
}
public static void main(String args[]){
int T=in.nextInt();
in.nextLine();
while(T-->0){
edges.clear();
vs.clear();
inDegree.clear();
ans=0;
n=0;
String s[]=in.nextLine().split(",");
for(int i=0;i<s.length;i++){
char start=s[i].charAt(0);
char end=s[i].charAt(2);
edges.add(new Edge(start,end));
inDegree.put(end,inDegree.getOrDefault(end,0)+1);
vs.add(start);
vs.add(end);
}
n=vs.size();
for(Character v:vs){
if(!inDegree.containsKey(v)){
inDegree.put(v,0);
}
}
/* System.out.println(vs.toString());
System.out.println(n);
System.out.println(inDegree.toString());
System.out.println(edges.toString());*/
topoSort(0);
System.out.println(ans);
}
}
}