自然数の分割
Posted feedbacks - Java
普通に再帰で。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import java.util.*;
public class PartNumber {
public static void main(String[] args) {
System.out.println(part(5, 3)); // => [[5, 0, 0], [4, 1, 0], ..., [0, 1, 4], [0, 0, 5]]
}
private static List<List<Integer>> part(int n, int m) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
List<Integer> item;
if (m == 1) {
item = new ArrayList<Integer>();
item.add(n);
res.add(item);
return res;
}
for (int i = n; i >= 0; i--) {
List<List<Integer>> r = part(n - i, m - 1);
for (List<Integer> l : r) {
item = new ArrayList<Integer>();
item.add(i);
item.addAll(l);
res.add(item);
}
}
return res;
}
}
|
動的計画法で。
(n, m) = (32, 8)で実行した場合。
----
234[ms]
[4, 4, 4, 4, 4, 4, 4, 4]
[3, 4, 4, 4, 4, 4, 4, 5]
[3, 3, 4, 4, 4, 4, 5, 5]
:
[0, 0, 0, 0, 0, 0, 1, 31]
[0, 0, 0, 0, 0, 0, 0, 32]
3319
(n, m) = (32, 8)で実行した場合。
----
234[ms]
[4, 4, 4, 4, 4, 4, 4, 4]
[3, 4, 4, 4, 4, 4, 4, 5]
[3, 3, 4, 4, 4, 4, 5, 5]
:
[0, 0, 0, 0, 0, 0, 1, 31]
[0, 0, 0, 0, 0, 0, 0, 32]
3319
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | import java.util.*;
public class PartNumber {
private static final Map<Key, Answer> answerTable = new HashMap<Key, Answer>();
public static void main(String[] args) {
long begin = System.currentTimeMillis();
Answer answer = execute(32, 8);
System.out.printf("%d[ms]%n", System.currentTimeMillis() - begin);
for (int[] a : answer.set) {
System.out.println(Arrays.toString(a));
}
System.out.println(answer.set.size());
}
public static Answer execute(int n, int m) {
Key key = new Key(n, m);
if(answerTable.containsKey(key)) {
return answerTable.get(key);
}
Answer answer = new Answer(key);
if(m <= 2) {
for (int i = 0; i <= n/2; i++) {
answer.set.add(new int[]{i, n-i});
}
} else {
for (int i = 0; i <= n/m; i++) {
answer.set.addAll(execute(n-i, m-1).marge(key, i).set);
}
}
answerTable.put(key, answer);
return answer;
}
static class Key {
final int n;
final int m;
Key(int n, int m) {
this.n = n;
this.m = m;
}
@Override
public int hashCode() {
return 17 * n ^ m;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof Key)) return false;
Key target = (Key) obj;
return (this.n == target.n && this.m == target.m);
}
}
static class Answer {
private final Key k;
private TreeSet<int[]> set;
Answer(Key k) {
this.k = k;
this.set = new TreeSet<int[]>(
new Comparator<int[]>() {
public int compare(int[] o1, int[] o2) {
assert o1.length == o2.length;
if(o1 == o2) return 0;
for (int i = 0; i < o1.length; i++) {
if(o1[i] != o2[i]) return o2[i] - o1[i];
}
return 0;
}
});
}
boolean add(int x, int[] a) {
assert a.length + 1 == k.m;
int[] a2 = new int[k.m];
a2[0] = x;
System.arraycopy(a, 0, a2, 1, a.length);
Arrays.sort(a2);
return set.add(a2);
}
Answer marge(Key k, int x) {
Answer answer = new Answer(k);
for (int[] a : this.set) {
answer.add(x, a);
}
return answer;
}
}
}
|
Javaが無いからと思ったのに、 完成したときには投稿されていたよ。 残念。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | public class Bunkatsu {
public static void main(String[] args) {
printSum( 6, 3 );
}
public static void printSum( int n, int m) {
if( m <= 0 || n < m )
return;
int[] prints = new int[m];
subPrintSum( prints, 0, n, m );
}
public static void subPrintSum( int[] prints, int p, int zan, int m ) {
if( p == m -1 ) {
prints[p] = zan;
for( int print : prints ) {
System.out.print( print );
System.out.print( "," );
}
System.out.println();
}
else
{
for( int i = zan ; i >= 0 ; --i ) {
prints[p] = i;
subPrintSum( prints, p+1, zan - i, m );
}
}
}
}
|
修正。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | package doukaku;
import java.util.*;
public class PartNumber {
private static final Map<Key, Answer> answerTable = new HashMap<Key, Answer>();
public static void main(String[] args) {
long begin = System.currentTimeMillis();
Answer answer = execute(32, 8);
System.out.printf("%d[ms]%n", System.currentTimeMillis() - begin);
for (Integer[] a : answer.set) {
System.out.println(Arrays.toString(a));
}
System.out.println(answer.set.size());
}
public static Answer execute(int n, int m) {
Key key = new Key(n, m);
if(answerTable.containsKey(key)) {
return answerTable.get(key);
}
Answer answer = new Answer(key);
if(m <= 2) {
for (int i = 0; i <= n/2; i++) {
answer.set.add(new Integer[]{i, n-i});
}
} else {
for (int i = 0; i <= n/m; i++) {
answer.set.addAll(execute(n-i, m-1).marge(key, i).set);
}
}
answerTable.put(key, answer);
return answer;
}
static class Key {
final int n;
final int m;
Key(int n, int m) {
this.n = n;
this.m = m;
}
@Override
public int hashCode() {
return 17 * n ^ m;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof Key)) return false;
Key target = (Key) obj;
return (this.n == target.n && this.m == target.m);
}
}
static class Answer {
private final Key k;
private TreeSet<Integer[]> set;
Answer(Key k) {
this.k = k;
this.set = new TreeSet<Integer[]>(
new Comparator<Integer[]>() {
public int compare(Integer[] o1, Integer[] o2) {
assert o1.length == o2.length;
if(o1 == o2) return 0;
for (int i = 0; i < o1.length; i++) {
if(o1[i] != o2[i]) return o2[i] - o1[i];
}
return 0;
}
});
}
boolean add(int x, Integer[] a) {
assert a.length + 1 == k.m;
Integer[] a2 = new Integer[k.m];
a2[0] = x;
System.arraycopy(a, 0, a2, 1, a.length);
Arrays.sort(a2, Collections.reverseOrder());
return set.add(a2);
}
Answer marge(Key k, int x) {
Answer answer = new Answer(k);
for (Integer[] a : this.set) {
answer.add(x, a);
}
return answer;
}
}
}
|
Javaはもうあるけど,短いのができたので載せてみる。 java PartNumber 5 3 みたいにして実行。 各行の最後のカンマは余分だと思うのだけど, 問題文にあわせてつけてみた。
1 2 3 4 5 6 7 8 9 10 11 12 | public class PartNumber {
public static void main(String[] args) throws Exception {
part("", Integer.parseInt(args[0]), Integer.parseInt(args[1]));
}
private static void part(String s, int n, int m) {
if (m == 1) {
System.out.println(s + n + ",");
} else for (int i = n; i >= 0; i--) {
if (n - i >= 0) part(s + i + ", ", n - i, m - 1);
}
}
}
|
しまった。if文がよぶんだった。
1 2 3 4 5 6 7 8 9 10 11 12 | public class PartNumber {
public static void main(String[] args) throws Exception {
part("[", Integer.parseInt(args[0]), Integer.parseInt(args[1]));
}
private static void part(String s, int n, int m) {
if (m == 1) {
System.out.println(s + n + "]");
} else for (int i = n; i >= 0; i--) {
part(s + i + ", ", n - i, m - 1);
}
}
}
|





herumi
#4099()
Rating1/1=1.00
[ reply ]