algorithm adventures in moving part iv - andstudy/forge GitHub Wiki
- μ΅λ 10000Km 거리μ λͺ©νμ§ κΉμ§ μ΅μμ κΈ°λ¦κ°μ μ°λ©΄μ λμ°©νλ λ°©λ²μ?
- μ΅λ 10000 + 1 + 100 Km λ₯Ό μΈλ±μ€λ‘ DP ν μ΄λΈμ λ§λ¬.
- κ° μμΉμμμ μ΅μ κΈ°λ¦κ°μ ꡬν΄μ DP ν μ΄λΈ μμ±
- DP ν μ΄λΈμ λλ©΄μ κΈ°λ¦κ°μ λμ μμΌλκ° λ΅μ ꡬνλ€.
- Wrong νλ², Presentation Error νλ², Solved.. μ€ λν€!
- μ μΆλ ₯μ΄ κΉνμ€λ½λ€μ;
// "Adventures in Moving - Part IV" Solution By Outbreak
#include <iostream>
#include <vector>
using namespace std;
//#define _TDD
//--------------------------------------------------------------------
namespace Solver
{
static const int IMPOSSIBLE_PRICE = 10000;
static const int MAX_DISTANCE = 10001;
static const int MAX_GAS_SIZE = 200;
static const int DEFAULT_GAS_SIZE = 100;
static vector<int> VPrice(MAX_DISTANCE+DEFAULT_GAS_SIZE,IMPOSSIBLE_PRICE);
// 1. > DP ν
μ΄λΈ μ΄κΈ°ν
void MakePriceTable()
{
int i;
for( i=0; i<MAX_DISTANCE+DEFAULT_GAS_SIZE; i++ )
{
VPrice[i] = IMPOSSIBLE_PRICE;
}
for( i=0; i<=DEFAULT_GAS_SIZE; i++ )
{
VPrice[i] = 0;
}
}
// 2. > DP ν
μ΄λΈ λ§λ€κΈ° - κ° μ£Όμ μλ₯Ό μ€μ¬μΌλ‘!
void InsertPrice( int dist, int price )
{
// νμ¬ μμΉμμ μ μΌ μΌ κ°κ²©
for(int i=1;i<=MAX_GAS_SIZE;i++)
{
if(VPrice[ dist+i ] > price)
{
VPrice[ dist+i ] = price;
}
}
}
// 3. > μ΅μ λΉμ© ꡬνκΈ°
int CalcMinimumPrice(int distance)
{
int price = 0;
// κ° μμΉμμμ μ£Όμ κ°κ²©μ λν΄ λκ°λ©΄μ μ΄ λΉμ©μ μ°μΆνλ€.
// λ°λ© μ κΈ°λ¦ν΅μ λ°μ΄ μ±μμ Έ μμ΄μΌ νλ―λ‘ κ·Έ λ§νΌμ λ κ°λ€κ³ μκ°νλ€.
for(int i=1; i<=distance+DEFAULT_GAS_SIZE; i++)
{
if (VPrice[i] == IMPOSSIBLE_PRICE)
{
return -1;
}
price += VPrice[i];
}
return price;
}
}
//--------------------------------------------------------------------
namespace Runner
{
void Execute(istream& in, ostream& out)
{
int sample = 0;
in >> sample;
while( sample-- )
{
int distance = 0, dist = 0, price = 0;
in >> distance;
Solver::MakePriceTable();
while(true)
{
in.get();
// κ°νμ΄ νκ° λμ€λ©΄ λ€μ μν μ²λ¦¬
if( in.peek() == '\n')
{
break;
}
in >> dist >> price;
if( in.fail() )
break;
Solver::InsertPrice(dist, price);
}
int result = Solver::CalcMinimumPrice(distance);
if( result == -1 )
{
out << "Impossible" << endl;
}
else
{
out << result << endl;
}
if( sample > 0 )
{
out << endl;
}
}
}
}
//--------------------------------------------------------------------
#ifdef _TDD
#include "unittest++.h"
struct TEST_BASE
{
stringstream input;
stringstream output;
};
TEST_FIXTURE(TEST_BASE, PresentationTest)
{
input <<
"2\n"
"\n"
"500\n"
"100 999\n"
"150 888\n"
"200 777\n"
"300 999\n"
"400 1009\n"
"450 1019\n"
"500 1399\n";
input << "\n";
input <<
"500\n"
"100 999\n"
"150 888\n"
"200 777\n"
"300 999\n"
"400 1009\n"
"450 1019\n"
"500 1399\n";
Runner::Execute(input, output);
CHECK_EQUAL( "450550\n\n450550\n", output.str());
}
#endif
//--------------------------------------------------------------------
int main()
{
#ifdef _TDD
UnitTest::RunAllTests();
#else
Runner::Execute(cin, cout);
#endif // _TDD
return 0;
}
-
μ£Όμ μ λ€λ¦΄ λλ§λ€ νμ ν±ν¬λ₯Ό κ½ μ±μμΌ νλ€λ κ°μ μ΄ μλ€λ©΄ μ΄κ²λ λ΅μ΄ λ μ μκ² μ§λ§, μμ 무μμ DP table λ‘ λ§λ€ κ²μΈκ°λ₯Ό μ λͺ» μκ°νλ€μ. μ©...
-
μλ‘ νΌ λ¬Έμ λ μ€μμ¨λ λκ°μ΄ νμκΈ° λλ¬Έμ λ°λ‘ μ¬λ¦¬μ§ μμ΅λλ€. :)
-
κ·Έλ¬λκΉ μλ μ½λλ μ λͺ» νΌ κ±°λΌλ κ±°.. T_T
/* @JUDGE_ID:parkpd 110401 Cpp "test" */ /* @BEGIN_OF_SOURCE_CODE */ #include <iostream> #include <vector> #include <set> #include <deque> #include <list> #include <stack> #include <string> #include <algorithm> #include <map> #include <limits> #include <assert.h> #include <iomanip> #include <math.h> #define _UNIT_TEST #ifdef _UNIT_TEST #include <Windows.h> #endif using namespace std; namespace ATUtil { bool IsInRange(int value, int from, int to) { return (from <= value) && (value <= to); } int ConvertToIndex(char c) { if ('a' <= c && c <= 'z') { return c - 'a'; } else { return -1; } } char ConvertToChar(int i) { return (char)i + 'a'; } #ifdef _UNIT_TEST class CStopWatch { public: CStopWatch() { m_StartTick = GetTickCount(); // gcc μμ μ λ μ μμΌλκΉ } ~CStopWatch() { cout << "Time passed : " << GetTickCount() - m_StartTick << " milisec.\n"; } int m_StartTick; }; #endif typedef map<int, int> IntDB; typedef vector<int> Ints; typedef list<int> IntList; }; using namespace ATUtil; #ifdef _UNIT_TEST #include "../UnitTest++/src/UnitTest++.h" #ifdef max #undef max #endif #ifdef min #undef min #endif int main() { UnitTest::RunAllTests(); char temp; cin >> temp; return 0; } #endif // code implement namespace ATCode { ////////////////////////////////////////////////////////////////////////// // CStation class CStation { public: CStation(int d, int c) : m_Dist(d), m_Cost(c), m_TotalCost(0) {} int m_Dist; int m_Cost; int m_TotalCost; }; ////////////////////////////////////////////////////////////////////////// // CStationNavi class CStationNavi { public: enum {MAX_STATIONS = 9}; // 100 μ΄μμ μ°λ£λ₯Ό λ¨κΈ°κΈ° μν΄, μμ 거리λ₯Ό λλ €μ€λ€. CStationNavi(int dist) : m_Dist(dist + 100) { // μΆλ°μ§λ μΌμ’ μ μ£Όμ μλ‘ μκ°νμ. // 미리 κ°μ§κ³ μλ κ°μ€ 100 λ§νΌμ λΊ κ±°λ¦¬μμ κ°μ€ 200 μ μ±μ λ€κ³ μκ°νκ³ μμνλ€. Input(-100, 0); } void Input(int d, int c) { m_Stations.push_back(CStation(d, c)); } template<typename InputIterator> void Inputs(InputIterator f, InputIterator t) { for (InputIterator i = f; i < t; i += 2) { Input(*i, *(i+ 1)); } } int CalcDirectCost(int from, int to) { if (-1 == m_CostTable[from][to]) { const int distBetweenStation = m_Stations[to].m_Dist - m_Stations[from].m_Dist; if (200 < distBetweenStation) { m_CostTable[from][to] = numeric_limits<int>::max(); // κ° μ μμ. } else { m_CostTable[from][to] = m_Stations[from].m_Cost * (distBetweenStation); } } return m_CostTable[from][to]; } int CalcCost(int from, int to) { // TODO : κ°μ€κ° λΆμ‘±νλ©΄ 무νλλ₯Ό 리ν΄ν΄μΌ νλ€. μ΄λ»κ²? // Cs-t = min(Cs-t, min(k=s-t)(Cs-k, Ck-t)) if ((from == to) || (from + 1 == to)) { return CalcDirectCost(from, to); } else { // Cs-t = min(Cs-t, min(k=s-t)(Cs-k, Ck-t)) int minCost = numeric_limits<int>::max(); for (int k = from + 1; k < to; ++k) { int cost = CalcCost(from, k) + CalcCost(k, to); if (cost < minCost) { minCost = cost; } } m_CostTable[from][to] = min(CalcDirectCost(from, to), minCost); return m_CostTable[from][to]; } } int Calc() { Input(m_Dist, 0); // λͺ©μ μ§λ μΌμ’ μ μ£Όμ μλ‘ μκ°νμ. // Cs-t = min(Cs-t, min(k=s-t)(Cs-k, Ck-t)) // case 1. // C0-2 = min(C0-2, C0-1 + C1-2) for (int r = 0; r < MAX_STATIONS; ++r) { for (int c = 0; c < MAX_STATIONS; ++c) { if (r == c) { m_CostTable[r][c] = 0; } else { m_CostTable[r][c] = -1; } } } const int numStations = (int)m_Stations.size(); int calcCost = 0; for (int diagonal = 1; diagonal <= numStations; ++diagonal) { for (int r = 0; r < numStations - diagonal; ++r) { int c = r + diagonal; //cout << r << c << "\n"; //m_CostTable[r][c] = //min(m_CostTable[r][c], //min(k)(m_CostTable[r][k] + m_CostTable[k][c]); calcCost = CalcCost(r, c); m_CostTable[r][c] = calcCost; } } return m_CostTable[0][numStations - 1]; } int m_Dist; vector<CStation> m_Stations; int m_CostTable[MAX_STATIONS][MAX_STATIONS]; }; /////////////////////////////////////////////////////////////// // CConsole class CConsole { public: static void ConsoleTest(istream& input, ostream& output); }; void CConsole::ConsoleTest(istream& input, ostream& output) { int testCount = 0; input >> testCount; for (int i = 0; i < testCount; ++i) { if (1 <= i) { output << "\n"; } int dist; input >> dist; CStationNavi navi(dist); int pos, price; while (input >> pos >> price) { navi.Input(pos, price); } output << navi.Calc() << "\n"; } }; } using namespace ATCode; #ifndef _UNIT_TEST int main() { CConsole::ConsoleTest(cin, cout); return 0; } #else // tests struct FixtureBase { FixtureBase() { } stringstream input; stringstream output; }; TEST_FIXTURE(FixtureBase, Case2) { int stations[] = {100, 999, 200, 1000}; CStationNavi n(300); n.Inputs(&stations[0], &stations[sizeof(stations) / sizeof(int)]); CHECK_EQUAL(0, n.Calc()); } TEST_FIXTURE(FixtureBase, Case1) { int stations[] = {50, 999}; CStationNavi n(100); n.Inputs(&stations[0], &stations[sizeof(stations) / sizeof(int)]); CHECK_EQUAL(0, n.Calc()); } TEST_FIXTURE(FixtureBase, ConsoleTest) { input << "1\n" "\n" "500\n" "100 999\n" "150 888\n" "200 777\n" "300 999\n" "400 1009\n" "450 1019\n" "500 1399\n"; CConsole::ConsoleTest(input, output); CHECK_EQUAL( "450550\n", output.str()); } #endif /* @END_OF_SOURCE_CODE */