前言
昨天看到一個演算法題,挺有意思的,大家分享下,這道題被定義為困難。
題目
學校要裝空調了!!!
9102年,學校終於要裝空調了,學生們都歡呼雀躍的期待著學校趕緊把空調裝好。但是學校招過來的安裝空調的人卻不夠了,同一時間只能安裝一個空調,這引起了大家的不滿。大家都希望學校能夠先裝自己宿舍,如果裝的太晚就要抗議。
假設學校共有 n 棟宿舍樓,每棟宿舍樓有 m 間宿舍,每間宿舍都有大小不同的忍受度。學校裝空調時,只能把同一棟樓的空調安裝完畢後才能安裝其他宿舍樓的空調。
作為校長精明能幹的助手,校長希望你能夠安排好學校安裝空調的順序,讓抗議的宿舍數最少。(增添人手的錢都用來買空調了,別想在招人了)
入參有三個,第一個輸入一個整數n,表示n棟宿舍樓;
第二個輸入一個整數m,表示每棟樓有m間宿舍;
接下來輸入一個n*
m的矩陣,表示每棟宿舍樓的每間宿舍的忍受度f(ij)。
(1 <= n <=20 ,1<=m <=1000,1<=f(ij)<=n *
m)。
註釋:忍受度:如果某個宿舍宿舍是所有宿舍(包含其他宿舍樓的宿舍)中第 x 個裝空調的(x > f_{ij}) , 那麼這個宿舍就要去抗議。
輸出最少的抗議的宿舍數。
示例1
輸入:
3
3
[[3,1,2],[6,5,8],[7,3,4]]
輸出:
2
注意
安裝空調的順序依次為:
(1,2),(1,3),(1,1)
(2,2),(2,1),(2,3)
(3,1),(3,2),(3,3)
實現程式碼
package solution70;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class Solution {
private int minCount = Integer.MAX_VALUE;
private int position = 0;//from 1
private int currentCount = 0;
private List<Floor> floors;
private int n;
private int m;
private List<Room> orderedRooms = new ArrayList<>();
public int solution(int n, int m, int[][] f) {
initData(n, m, f);
this.start();
return minCount;
}
private void initData(int n, int m, int[][] f) {
this.n = n;
this.m = m;
int i = 0;
int j;
ArrayList<Floor> floors = new ArrayList<>();
for (; i < n; i++) {
ArrayList<Room> rooms = new ArrayList<>();
for (j = 0; j < m; j++) {
rooms.add(new Room(false, f[i][j], i + 1, j + 1));
}
sortRooms(rooms);
Floor floor = new Floor(false, rooms);
floors.add(floor);
}
this.floors = floors;
}
private void sortRooms(List<Room> rooms) {
rooms.sort(new Comparator<Room>() {
@Override
public int compare(Room o1, Room o2) {
return o1.getEndurance() - o2.getEndurance();
}
});
}
private void start() {
boolean allChecked = true;
FloorResult result;
for (Floor f :
floors) {
if (!f.isChecked()) {
f.setChecked(true);
result = calculateFloor(f);
allChecked = false;
position -= result.getIterateCount();
currentCount -= result.getCount();
f.setChecked(false);
}
}
//the last floor
if (allChecked) {
if (currentCount < minCount) {
minCount = currentCount;
printRoom();
}
System.out.println("min:" + minCount + " and now:" + currentCount);
}
}
private void printRoom() {
for (Floor f :
this.floors) {
System.out.println("-----------------");
for (Room m :
f.getRooms()) {
System.out.println("(" + m.getPosition() + "," + m.getEndurance() + ")");
}
System.out.println("-----------------");
}
}
private FloorResult calculateFloor(Floor floor) {
boolean afterShouldProtest = false;
FloorResult result = new FloorResult();
int reservedPosition;
int reservedCount;
boolean isFound = false;
// List<Room> cur = new ArrayList<>();
for (Room r :
floor.getRooms()) {
if (!r.isChecked()) {
result.incrIterateCount();
position++;
r.setChecked(true);
isFound = false;
//cur.add(r);
if (r.getEndurance() < position) {
for (Room m :
floor.getRooms()) {
/* boolean checked = m.isChecked();
m.setChecked(true);*/
if (!m.isChecked() && m.getEndurance() >= position) {
//skip
m.setChecked(true);
isFound = true;
m.setPosition(position);
break;
}
}
r.setPosition(0);
currentCount++;
result.incrCount();
if (!afterShouldProtest) {
afterShouldProtest = true;
}
if (currentCount >= minCount) {
//restore
for (Room k :
floor.getRooms()) {
k.setChecked(false);
}
return result;
}
} else {
r.setPosition(position);
}
}
}
//restore
for (Room r :
floor.getRooms()) {
r.setChecked(false);
}
reservedPosition = position;//reserve
reservedCount = currentCount;
//next floor
start();
position = reservedPosition;
currentCount = reservedCount;
return result;
}
private static class Floor {
private boolean isChecked;
private List<Room> rooms;
public Floor(boolean isChecked, List<Room> rooms) {
this.isChecked = isChecked;
this.rooms = rooms;
}
public boolean isChecked() {
return isChecked;
}
public void setChecked(boolean checked) {
isChecked = checked;
}
public List<Room> getRooms() {
return rooms;
}
public void setRooms(List<Room> rooms) {
this.rooms = rooms;
}
public void addRoom(Room room) {
rooms.add(room);
}
}
private static class Room {
private boolean isChecked;
private int endurance;
private int x;
private int y;
private int position;
public Room(boolean isChecked, int endurance, int x, int y) {
this.isChecked = isChecked;
this.endurance = endurance;
this.x = x;
this.y = y;
}
public boolean isChecked() {
return isChecked;
}
public void setChecked(boolean checked) {
isChecked = checked;
}
public int getEndurance() {
return endurance;
}
public void setEndurance(int endurance) {
this.endurance = endurance;
}
@Override
public String toString() {
return "Room{" +
"isChecked=" + isChecked +
", endurance=" + endurance +
", x=" + x +
", y=" + y +
'}';
}
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
}
private static class FloorResult {
private int iterateCount;
private int count;
public FloorResult() {
}
public FloorResult(int iterateCount, int count) {
this.iterateCount = iterateCount;
this.count = count;
}
public int getIterateCount() {
return iterateCount;
}
public void setIterateCount(int iterateCount) {
this.iterateCount = iterateCount;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public void incrIterateCount() {
iterateCount++;
}
public void incrCount() {
count++;
}
}
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結