• ACM学习历程—Hihocoder 1290 Demo Day(动态规划)


    http://hihocoder.com/problemset/problem/1290

    这题是这次微软笔试的第三题,过的人比第一题少一点,这题一眼看过去就是动态规划,不过转移方程貌似不是很简单,调试了比较久才正确,不过好在是1A,但是最后只留了一个小时多一点给B题,也导致了B题最后也没能AC掉。首先状态是很好确定的p[i][j][k]表示走到第i行第j个格子时,方向是k的情况下的最小改变格子数目。(k from {0, 1})而且由于只有往下和往右走,所以中间过程进行转移时改变的格子不会影响后续过程中的转移,所以只需要分析p[i][j][0]和p[i][j][1]分别怎么由上面和左边的格子得到。情况比较多,基本上在代码里就可以看明白,不过需要对几处边界条件判断一下,比如第一列无法由左边格子得到,第一行无法由上面的格子得到,还有就是向下和向右撞到边界的时候。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <set>
    #include <map>
    #include <queue>
    #include <vector>
    #include <string>
    #define LL long long
    
    using namespace std;
    
    int n, m;
    char str[105][105];
    int p[105][105][2];
    
    void input()
    {
        for (int i = 0; i < n; ++i)
            scanf("%s", str[i]);
        memset(p, -1, sizeof(p));
    }
    
    void work()
    {
        int t;
        if (str[0][0] == '.') p[0][0][0] = 0;
        else p[0][0][0] = 1;
        if (m == 1 || str[0][1] == 'b') p[0][0][1] = 0;
        else p[0][0][1] = 1;
        for (int i = 0; i < n; ++i)
        {
            for (int j = 0; j < m; ++j)
            {
                if (i == 0 && j == 0) continue;
                if (j == 0)
                {
                    //left
                    if (i+1 == n || str[i+1][j] == 'b')
                        p[i][j][0] = p[i-1][j][1];
                    else
                        p[i][j][0] = p[i-1][j][1]+1;
                    if (str[i][j] == 'b') p[i][j][0]++;
    
                    //bottom
                    p[i][j][1] = p[i-1][j][1];
                    if (str[i][j] == 'b') p[i][j][1]++;
                }
                else
                {
                    //left
                    p[i][j][0] = p[i][j-1][0];
                    if (str[i][j] == 'b') p[i][j][0]++;
                    if (i > 0)
                    {
                        t = p[i-1][j][1];
                        if (str[i][j] == 'b') t++;
                        if (i+1 == n || str[i+1][j] == 'b')
                            p[i][j][0] = min(p[i][j][0], t);
                        else
                            p[i][j][0] = min(p[i][j][0], t+1);
                    }
    
                    //bottom
                    p[i][j][1] = p[i][j-1][0];
                    if (str[i][j] == 'b') p[i][j][1]++;
                    if (!(j+1 == m || str[i][j+1] == 'b'))
                        p[i][j][1]++;
                    if (i > 0)
                    {
                        t= p[i-1][j][1];
                        if (str[i][j] == 'b') t++;
                        p[i][j][1] = min(p[i][j][1], t);
                    }
                }
            }
        }
        printf("%d
    ", min(p[n-1][m-1][0], p[n-1][m-1][1]));
    }
    
    int main()
    {
        //freopen("test.in", "r", stdin);
        while (scanf("%d%d", &n, &m) != EOF)
        {
            input();
            work();
        }
        return 0;
    }
    View Code
  • 相关阅读:
    【转】iOS WKWebView基本使用总结
    【转】让JS在Android/iOS WebView中反调接口统一,调用更容易
    关于Xcode的Other Linker Flags
    SonarQube+Jenkins+Cppcheck实现C++代码扫描
    YAPI工具配置LDAP统一用户认证
    LDAP脚本批量导出用户
    软件配置库备份之删除指定日期前的备份文件
    软件测试中测试环境独立性的原因
    [SVN]TortoiseSVN工具培训5─常见问题解决
    [SVN]TortoiseSVN工具培训4─客户端常用操作命令
  • 原文地址:https://www.cnblogs.com/andyqsmart/p/5371463.html
Copyright © 2020-2023  润新知