Last active
August 29, 2015 14:05
-
-
Save kazurof/190aa8de69fd60bea3d5 to your computer and use it in GitHub Desktop.
sample code for https://paiza.jp/poh/kirishima
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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