题解 | #LP钱不够#动态规划新手版

LP钱不够

https://ac.nowcoder.com/acm/problem/14582

思路:

00 01 02 03 04

10 11 12 13 14

20 21 22 23 24

30 31 32 33 34

40 41 42 43 44

基值:对于任意位置Aij(假如是11), 它的最小花费由Max{10, 01}决定。你想呀,吃货只能往下走, 或者往右走,按照逆向思维,你只能看到吃货从上边来,或者从左边来。

特殊位置:对于第0行(00, 01 , 02, ..), 和第0列(00, 10, 20, ..), 站在这个位置(第0行)只能看到吃货从左边来, 就没有从上边来的,因为没有地。同样的,站在第0列,只能看到吃货从上边来,而没有从左边来的。所以,00位置的花费是固定的, 01位置的花费只由00位置决定,即01位置的花费是 00+01。 相同的, 02位置的花费只由01位置决定,即02位置的花费是 01+02.在列上也是如此。

通过特殊位置(第0行, 第0列), 我们可以一层一层往44位置推。记住,特殊位置的值已经得出。

所以, 11位置的值为 Max{10, 01}, 21位置的值为 Max{20, 11}, ....不过,只有你先推出 11位置的花费, 才能推21位置的花费, 12位置的花费。也就是说, 你若是按照行优先的原则推, 且从左往右,你最终能推出 44 位置的最小花费。

#include<vector>
#include<cmath>
using namespace std;
int main()
{
    int x;
    int n;
    cin>> x;
    for(int k = 0; k < x - 1; ++k)
    {
        cin>> n;
        vector<vector<int>> v(n, vector<int>(n));
        int i, j;
        for(i = 0; i < n; ++i)
        {
            for(j = 0; j < n; ++j)
            {
                cin>> v[i][j];
            }
        }
        for(i = 1; i < n; ++i)
        {
            v[i][0] = v[i][0] + v[i - 1][0];
            v[0][i] = v[0][i] + v[0][i - 1];
        }
        for(i = 1; i < n; ++i)
        {
            for(j = 1; j < n; ++j)
            {
                v[i][j] += min(v[i - 1][j], v[i][j - 1]);
            }
        }
        cout<<v[n - 1][n - 1]<<'\n';
    }
    
    //按照格式要求, 最后一次求解独立出来,这里增大了代码规模
    cin>> n;
        vector<vector<int>> v(n, vector<int>(n));
        int i, j;
        for(i = 0; i < n; ++i)
        {
            for(j = 0; j < n; ++j)
            {
                cin>> v[i][j];
            }
        }
        for(i = 1; i < n; ++i)
        {
            v[i][0] = v[i][0] + v[i - 1][0];
            v[0][i] = v[0][i] + v[0][i - 1];
        }
        for(i = 1; i < n; ++i)
        {
            for(j = 1; j < n; ++j)
            {
                v[i][j] += min(v[i - 1][j], v[i][j - 1]);
            }
        }
        cout<<v[n - 1][n - 1];
}
全部评论

相关推荐

评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务