Skip to content

Instantly share code, notes, and snippets.

@kazurof
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kazurof/190aa8de69fd60bea3d5 to your computer and use it in GitHub Desktop.
Save kazurof/190aa8de69fd60bea3d5 to your computer and use it in GitHub Desktop.
import java.util.List;
import java.util.OptionalInt;
import java.util.Scanner;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Main {
/**
* 全ての会社を選択した場合の人数
*/
static int numOfMemberIfUseAll;
/**
* 必要な人数
*/
static int requiedNumOfMember;
/**
* 会社の数
*/
static int numOfCompany;
public static void main(String[] args) {
List<Company> companyList = null;
// 入力データの読み込み。
try (Scanner scanner = new Scanner(System.in)) {
requiedNumOfMember = scanner.nextInt();
numOfCompany = scanner.nextInt();
IntStream s = IntStream.range(0, numOfCompany);
companyList = s.mapToObj(i ->
new Company(scanner.nextInt(), scanner.nextInt()))
.collect(Collectors.toList());
};
numOfMemberIfUseAll = companyList.stream()
.mapToInt(company -> company.members).sum();
CostByNumOfMember costByNumOfMember
= new CostByNumOfMember(numOfMemberIfUseAll);
companyList.stream().map((Company company) -> {
IntStream s = IntStream.range(company.members,
numOfMemberIfUseAll);
// s を降順にするため、mapしてからforEachする。
s.map(i -> numOfMemberIfUseAll - i + company.members - 1)
.forEach(i -> costByNumOfMember.process(i, company));
return company;
}).forEach((company) -> {
costByNumOfMember
.updateCostByNumOfMember(company.cost, company.members);
});
// 結果の検索と表示
int result = costByNumOfMember
.getLeastCostForMembers(requiedNumOfMember);
System.out.println(result);
}
}
class CostByNumOfMember {
/**
* 添字人数になるように会社を選んだ組み合わせの時の総コスト。
* {@link #NOT_ASSIGNED} の場合はそのような組み合わせは存在しない。
*/
int[] value;
/**
* {@link #value} において、そのような人数に対する会社の
* 組み合わせは存在しないことを表現する。
*/
static final int NOT_ASSIGNED = -1;
CostByNumOfMember(int numOfMemberIfUseAll) {
value = new int[numOfMemberIfUseAll + 1];
IntStream s = IntStream.range(0, value.length);
s.forEach(i -> {
value[i] = NOT_ASSIGNED;
});
}
int get(int numOfMember) {
return value[numOfMember];
}
void set(int numOfMember, int newCost) {
value[numOfMember] = newCost;
}
void updateCostByNumOfMember(int newCost, int members) {
if (value[members] == CostByNumOfMember.NOT_ASSIGNED
|| newCost < value[members]) {
value[members] = newCost;
}
}
void process(int numOfMember, Company company) {
int costWithoutThisCompany
= get(numOfMember - company.members);
if (0 < costWithoutThisCompany) {
updateCostByNumOfMember(costWithoutThisCompany
+ company.cost, numOfMember);
}
}
int getLeastCostForMembers(int numOfMember) {
IntStream s = IntStream.range(numOfMember, value.length);
OptionalInt result = s.filter(i -> value[i] >= 0)
.map(i -> value[i]).min();
return result.getAsInt();
}
}
class Company {
Company(int members, int cost) {
this.members = members;
this.cost = cost;
}
int members;
int cost;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment