动态编程状态计算

时间:2018-06-02 17:05:41

标签: c++ dynamic state

问题:

Fox Ciel is writing an AI for the game Starcraft and she needs your help. 



In Starcraft, one of the available units is a mutalisk. Mutalisks are very useful for harassing Terran bases. Fox Ciel has one mutalisk. The enemy base contains one or more Space Construction Vehicles (SCVs). Each SCV has some amount of hit points. 



When the mutalisk attacks, it can target up to three different SCVs.
The first targeted SCV will lose 9 hit points.
The second targeted SCV (if any) will lose 3 hit points.
The third targeted SCV (if any) will lose 1 hit point.
If the hit points of a SCV drop to 0 or lower, the SCV is destroyed. Note that you may not target the same SCV twice in the same attack. 



You are given a int[] HP containing the current hit points of your enemy's SCVs. Return the smallest number of attacks in which you can destroy all these SCVs.

Constraints-
-   x will contain between 1 and 3 elements, inclusive.
-   Each element in x will be between 1 and 60, inclusive.

解决方案是:

int minimalAttacks(vector<int> x)
{
    int dist[61][61][61];
    memset(dist, -1, sizeof(dist));
    dist[0][0][0] = 0;
    for (int total = 1; total <= 180; total++) {
        for (int i = 0; i <= 60 && i <= total; i++) {
            for (int j = max(0, total - i - 60); j <= 60 && i + j <= total; j++) {
                // j >= max(0, total - i - 60) ensures that k <= 60
                int k = total - (i + j);
                int & res = dist[i][j][k];

                res = 1000000;
                // one way to avoid doing repetitive work in enumerating
                // all options is to use c++'s next_permutation,
                // we first createa vector:
                vector<int> curr = {i,j,k};
                sort(curr.begin(), curr.end()); //needs to be sorted
                // which will be permuted 
                do {
                    int ni = max(0, curr[0] - 9);
                    int nj = max(0, curr[1] - 3);
                    int nk = max(0, curr[2] - 1);
                    res = std::min(res, 1 + dist[ni][nj][nk] );

                } while (next_permutation(curr.begin(), curr.end()) );
            }
        }
    }
    // get the case's respective hitpoints:
    while (x.size() < 3) {
        x.push_back(0); // add zeros for missing SCVs
    }
    int a = x[0], b = x[1], c = x[2];        
    return dist[a][b][c];
}

据我所知,此解决方案首先计算所有可能状态的最佳结果,然后简单地匹配查询的位置并显示结果。但我不明白这段代码的编写方式。我可以看到无处编辑dist [i] [j] [k]值。默认情况下为-1。那么,当我查询任何dist [i] [j] [k]时,我会得到一个不同的价值? 有人可以解释一下代码吗?

谢谢!

0 个答案:

没有答案