#include <cstdio> #include <algorithm> typedef unsigned long long UInt64; typedef int Int32; Int32 g_totalNumberOfCups; UInt64 *g_costToCheck; UInt64 g_minimumCost; bool *g_isCupDefined; inline UInt64 costToCheck(Int32 i, Int32 j) { return g_costToCheck[i * g_totalNumberOfCups + j]; } void readInput() { scanf("%i", &g_totalNumberOfCups); g_costToCheck = new UInt64[g_totalNumberOfCups * g_totalNumberOfCups]; for (Int32 i = 0; i < g_totalNumberOfCups; ++i) for (Int32 j = i; j < g_totalNumberOfCups; ++j) scanf("%llu", g_costToCheck + i * g_totalNumberOfCups + j); } UInt64 minimumCostToDefine(Int32 i) { UInt64 cost = costToCheck(i, i); Int32 left = i; Int32 right = i; for (Int32 j = i - 1; j >= 0 && g_isCupDefined[j]; --j) left = j; for (Int32 j = i + 1; j < g_totalNumberOfCups && g_isCupDefined[j]; ++j) right = j; for (Int32 u = left; u <= i; ++u) for (Int32 v = i; v <= right; ++v) if (costToCheck(u, v) < cost) cost = costToCheck(u, v); return cost; } void walk(UInt64 currentCost, Int32 currentNumberOfDefinedCups) { if (currentNumberOfDefinedCups == g_totalNumberOfCups) { if (currentCost < g_minimumCost) g_minimumCost = currentCost; return; } for (Int32 i = 0; i < g_totalNumberOfCups; ++i) { if (g_isCupDefined[i]) continue; UInt64 newCost = currentCost + minimumCostToDefine(i); if (newCost < g_minimumCost) { g_isCupDefined[i] = true; walk(newCost, currentNumberOfDefinedCups + 1); g_isCupDefined[i] = false; } } } UInt64 minimumCostBound() { UInt64 bound = 0; for (Int32 i = 0; i < g_totalNumberOfCups; ++i) bound += costToCheck(i, i); return bound; } UInt64 solve() { g_isCupDefined = new bool [g_totalNumberOfCups]; for (Int32 i = 0; i < g_totalNumberOfCups; ++i) g_isCupDefined[i] = false; g_minimumCost = minimumCostBound(); walk(0, 0); return g_minimumCost; } int main() { readInput(); printf("%llu\n", solve()); return 0; }
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 94 95 96 97 98 99 100 101 102 103 | #include <cstdio> #include <algorithm> typedef unsigned long long UInt64; typedef int Int32; Int32 g_totalNumberOfCups; UInt64 *g_costToCheck; UInt64 g_minimumCost; bool *g_isCupDefined; inline UInt64 costToCheck(Int32 i, Int32 j) { return g_costToCheck[i * g_totalNumberOfCups + j]; } void readInput() { scanf("%i", &g_totalNumberOfCups); g_costToCheck = new UInt64[g_totalNumberOfCups * g_totalNumberOfCups]; for (Int32 i = 0; i < g_totalNumberOfCups; ++i) for (Int32 j = i; j < g_totalNumberOfCups; ++j) scanf("%llu", g_costToCheck + i * g_totalNumberOfCups + j); } UInt64 minimumCostToDefine(Int32 i) { UInt64 cost = costToCheck(i, i); Int32 left = i; Int32 right = i; for (Int32 j = i - 1; j >= 0 && g_isCupDefined[j]; --j) left = j; for (Int32 j = i + 1; j < g_totalNumberOfCups && g_isCupDefined[j]; ++j) right = j; for (Int32 u = left; u <= i; ++u) for (Int32 v = i; v <= right; ++v) if (costToCheck(u, v) < cost) cost = costToCheck(u, v); return cost; } void walk(UInt64 currentCost, Int32 currentNumberOfDefinedCups) { if (currentNumberOfDefinedCups == g_totalNumberOfCups) { if (currentCost < g_minimumCost) g_minimumCost = currentCost; return; } for (Int32 i = 0; i < g_totalNumberOfCups; ++i) { if (g_isCupDefined[i]) continue; UInt64 newCost = currentCost + minimumCostToDefine(i); if (newCost < g_minimumCost) { g_isCupDefined[i] = true; walk(newCost, currentNumberOfDefinedCups + 1); g_isCupDefined[i] = false; } } } UInt64 minimumCostBound() { UInt64 bound = 0; for (Int32 i = 0; i < g_totalNumberOfCups; ++i) bound += costToCheck(i, i); return bound; } UInt64 solve() { g_isCupDefined = new bool [g_totalNumberOfCups]; for (Int32 i = 0; i < g_totalNumberOfCups; ++i) g_isCupDefined[i] = false; g_minimumCost = minimumCostBound(); walk(0, 0); return g_minimumCost; } int main() { readInput(); printf("%llu\n", solve()); return 0; } |