Add tags

Add tags to the following comment
  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
104
105
106
107
108
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <limits>
#include <cassert>

#define REP(i, b, e) for (size_t i = b; i < e; ++i)
#define REPE(i, b, e) for (size_t i = b; i <= e; ++i)

void fill(std::vector<long>& v, long value)
{
    std::fill(v.begin(), v.end(), value);
}

int main()
{
    const size_t max_x = 1000;

    std::string s;

    std::getline(std::cin, s);

    size_t n, m;

    std::istringstream(s) >> n >> m;

    assert(2 <= n && n <= 150);

    assert(m <= (n + 1) / 2);

    std::vector<std::vector<long> > slip(n + 3, std::vector<long>(max_x, -1)); // -1 means there is no stone

    fill(slip[0], 0); // start shore (0 is dummy value)

    fill(slip[n + 1], 0); // goal shore (0 is dummy value)

    fill(slip[n + 2], 0); // goal shore (0 is dummy value)

    REPE(y, 1, n)
    {
        std::getline(std::cin, s);

        std::istringstream sin(s);

        size_t k;

        sin >> k;

        assert(k <= 10);

        for (; k; --k)
        {
            size_t x;

            long d;

            sin >> x >> d;

            assert(1 <= x && x <= max_x);

            assert(1 <= d && d <= 1000);

            --x; // now starts with 0 not 1

            slip[y][x] = d;
        }
    }

    std::vector<std::vector<std::vector<long> > > dp(n + 3,
        std::vector<std::vector<long> >(max_x,
            std::vector<long>(m + 1, std::numeric_limits<long>::max())));

    dp.front().swap(
        std::vector<std::vector<long> >(max_x,
            std::vector<long>(m + 1, 0)));

    REPE(y1, 0, n) REP(x1, 0, max_x) if (slip[y1][x1] >= 0) // source
    {
        REPE(y2, y1 + 1, y1 + 2) REP(x2, 0, max_x) if (slip[y2][x2] >= 0) // destinition
        {
            const size_t now_jumped = y2 - y1 - 1;

            assert(now_jumped == 0 || now_jumped == 1);

            for (size_t old_jumped = 0; old_jumped + now_jumped <= m; ++old_jumped)
            {
                if (dp[y1][x1][old_jumped] != std::numeric_limits<long>::max())
                {
                    long& src = dp[y1][x1][old_jumped];

                    long& dst = dp[y2][x2][old_jumped + now_jumped];

                    dst = std::min(dst, src + (slip[y1][x1] + slip[y2][x2]) * long(x2 > x1 ? x2 - x1 : x1 - x2));
                }
            }
        }
    }

    long result = std::numeric_limits<long>::max();

    REPE(y, n + 1, n + 2) REP(x, 0, max_x) REPE(jumped, 0, m) // goal shore
    {
        result = std::min(result, dp[y][x][jumped]);
    }

    std::cout << result << std::endl;
}

Add tags

The input will be splited to tags with space.

Index

Feed

Other

Link

Pathtraq

loading...