using System;
public class Test
{
private static int[,] Assing(int[] subjects, int[] controls, int count) {
if (count * subjects.Length > controls.Length) {
throw new ArgumentException();
}
Array.Sort(subjects);
Array.Sort(controls);
var subjTimesCount = new int[subjects.Length*count];
for (var i = 0 ; i < subjects.Length ; i++) {
for (var j = 0 ; j != count ; j++) {
subjTimesCount[i*count + j] = subjects[i];
}
}
var mem = new int[subjTimesCount.Length,controls.Length];
for (var i = 0; i < subjects.Length; i++) {
for (var j = 0; j != count; j++) {
mem[i,j] = -1;
}
}
var assignments = new int[subjTimesCount.Length];
var x = RecAssign(subjTimesCount, controls, mem, 0, 0, assignments);
Console.WriteLine(x);
var res = new int[subjects.Length,count];
for (var i = 0; i < subjects.Length; i++) {
for (var j = 0; j != count; j++) {
res[i, j] = assignments[i*count + j];
}
}
return res;
}
private static int RecAssign(int[] subjects, int[] controls, int[,] mem, int sp, int cp, int[] assignments) {
if (sp == subjects.Length) {
return 0;
}
if (mem[sp, cp] > 0) {
return mem[sp, cp];
}
var res = Math.Abs(subjects[sp] - controls[cp])
+ RecAssign(subjects, controls, mem, sp + 1, cp + 1, assignments);
assignments[sp] = cp;
if (cp+1+subjects.Length-sp < controls.Length) {
var alt = RecAssign(subjects, controls, mem, sp, cp + 1, assignments);
if (alt < res) {
res = alt;
} else {
assignments[sp] = cp;
}
}
mem[sp, cp] = res;
return res;
}
static void Main() {
var subj = new[] {190, 100};
var ctrl = new[] {70, 180, 220, 240, 500, 600, 600};
var res = Assing(subj, ctrl, 2);
for (var i = 0 ; i != subj.Length ; i++) {
for (var j = 0; j != 2; j++) {
Console.Error.WriteLine(
"{0}:{1} -- subj={2} loc={3} diff:{4}"
, i
, j
, subj[i]
, ctrl[res[i,j]]
, Math.Abs(subj[i] - ctrl[res[i,j]])
);
}
}
}
}
dXNpbmcgU3lzdGVtOwoKcHVibGljIGNsYXNzIFRlc3QKewogICAgICAgIHByaXZhdGUgc3RhdGljIGludFssXSBBc3NpbmcoaW50W10gc3ViamVjdHMsIGludFtdIGNvbnRyb2xzLCBpbnQgY291bnQpIHsKICAgICAgICAgICAgaWYgKGNvdW50ICogc3ViamVjdHMuTGVuZ3RoID4gY29udHJvbHMuTGVuZ3RoKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBBcnJheS5Tb3J0KHN1YmplY3RzKTsKICAgICAgICAgICAgQXJyYXkuU29ydChjb250cm9scyk7CiAgICAgICAgICAgIHZhciBzdWJqVGltZXNDb3VudCA9IG5ldyBpbnRbc3ViamVjdHMuTGVuZ3RoKmNvdW50XTsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAgOyBpIDwgc3ViamVjdHMuTGVuZ3RoIDsgaSsrKSB7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMCA7IGogIT0gY291bnQgOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICBzdWJqVGltZXNDb3VudFtpKmNvdW50ICsgal0gPSBzdWJqZWN0c1tpXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgbWVtID0gbmV3IGludFtzdWJqVGltZXNDb3VudC5MZW5ndGgsY29udHJvbHMuTGVuZ3RoXTsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdWJqZWN0cy5MZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogIT0gY291bnQ7IGorKykgewogICAgICAgICAgICAgICAgICAgIG1lbVtpLGpdID0gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIGFzc2lnbm1lbnRzID0gbmV3IGludFtzdWJqVGltZXNDb3VudC5MZW5ndGhdOwogICAgICAgICAgICB2YXIgeCA9IFJlY0Fzc2lnbihzdWJqVGltZXNDb3VudCwgY29udHJvbHMsIG1lbSwgMCwgMCwgYXNzaWdubWVudHMpOwogICAgICAgICAgICBDb25zb2xlLldyaXRlTGluZSh4KTsKICAgICAgICAgICAgdmFyIHJlcyA9IG5ldyBpbnRbc3ViamVjdHMuTGVuZ3RoLGNvdW50XTsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdWJqZWN0cy5MZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogIT0gY291bnQ7IGorKykgewogICAgICAgICAgICAgICAgICAgIHJlc1tpLCBqXSA9IGFzc2lnbm1lbnRzW2kqY291bnQgKyBqXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmVzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIHN0YXRpYyBpbnQgUmVjQXNzaWduKGludFtdIHN1YmplY3RzLCBpbnRbXSBjb250cm9scywgaW50WyxdIG1lbSwgaW50IHNwLCBpbnQgY3AsIGludFtdIGFzc2lnbm1lbnRzKSB7CiAgICAgICAgICAgIGlmIChzcCA9PSBzdWJqZWN0cy5MZW5ndGgpIHsKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChtZW1bc3AsIGNwXSA+IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiBtZW1bc3AsIGNwXTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgcmVzID0gTWF0aC5BYnMoc3ViamVjdHNbc3BdIC0gY29udHJvbHNbY3BdKQogICAgICAgICAgICAgICAgICAgICsgUmVjQXNzaWduKHN1YmplY3RzLCBjb250cm9scywgbWVtLCBzcCArIDEsIGNwICsgMSwgYXNzaWdubWVudHMpOwogICAgICAgICAgICBhc3NpZ25tZW50c1tzcF0gPSBjcDsKICAgICAgICAgICAgaWYgKGNwKzErc3ViamVjdHMuTGVuZ3RoLXNwIDwgY29udHJvbHMuTGVuZ3RoKSB7CiAgICAgICAgICAgICAgICB2YXIgYWx0ID0gUmVjQXNzaWduKHN1YmplY3RzLCBjb250cm9scywgbWVtLCBzcCwgY3AgKyAxLCBhc3NpZ25tZW50cyk7CiAgICAgICAgICAgICAgICBpZiAoYWx0IDwgcmVzKSB7CiAgICAgICAgICAgICAgICAgICAgcmVzID0gYWx0OwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBhc3NpZ25tZW50c1tzcF0gPSBjcDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBtZW1bc3AsIGNwXSA9IHJlczsKICAgICAgICAgICAgcmV0dXJuIHJlczsKICAgICAgICB9CiAgICAgICAgc3RhdGljIHZvaWQgTWFpbigpIHsKICAgICAgICAgICAgdmFyIHN1YmogPSBuZXdbXSB7MTkwLCAxMDB9OwogICAgICAgICAgICB2YXIgY3RybCA9IG5ld1tdIHs3MCwgMTgwLCAyMjAsIDI0MCwgNTAwLCA2MDAsIDYwMH07CiAgICAgICAgICAgIHZhciByZXMgPSBBc3Npbmcoc3ViaiwgY3RybCwgMik7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwIDsgaSAhPSBzdWJqLkxlbmd0aCA7IGkrKykgewogICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogIT0gMjsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgQ29uc29sZS5FcnJvci5Xcml0ZUxpbmUoCiAgICAgICAgICAgICAgICAgICAgICAgICJ7MH06ezF9IC0tIHN1Ymo9ezJ9IGxvYz17M30gZGlmZjp7NH0iCiAgICAgICAgICAgICAgICAgICAgLCAgIGkKICAgICAgICAgICAgICAgICAgICAsICAgagogICAgICAgICAgICAgICAgICAgICwgICBzdWJqW2ldCiAgICAgICAgICAgICAgICAgICAgLCAgIGN0cmxbcmVzW2ksal1dCiAgICAgICAgICAgICAgICAgICAgLCAgIE1hdGguQWJzKHN1YmpbaV0gLSBjdHJsW3Jlc1tpLGpdXSkKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQp9