• uva 1291(dp)


    题意:有一台跳舞机,中间是0。上左下右分别代表1 2 3 4,初始状态人站在中间。两仅仅脚都踏在0上,然后给出一段序列以0为结束,要按顺序踩出来,从0踏到四个方向须要消耗2点能量,从一个方向到相邻的方向消耗3点能量,从一个方向到对面方向消耗4点能量,在一个方向原地再踩一次消耗1点能量,问把全部序列踩完最少消耗多少能量。
    题解:f[i][j][k]表示踩前i步左脚在方向j上右脚在方向k上最少消耗多少能量。那么就要分两种情况讨论:
    (1)f[i][j][a[i]] 的前一步是f[i - 1][a[i - 1]][k]或f[i - 1][k][a[i - 1]]。这两种情况再加上这一步移动消耗能量取较小值。
    (2)f[i][a[i]][j]和上面相似
    结果在f[n][a[n]][k]和f[n][k][a[n]]中取最小值就是解。

    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    #include <algorithm>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    const int N = 100000;
    int n, a[N], f[N][5][5];
    
    int Count(int x, int y) {
        if (x == 0)
            return 2;
        int temp = fabs(x - y);
        if (temp == 0)
            return 1;
        if (temp % 2)
            return 3;
        return 4;
    }
    
    int main() {
        while (1) {
            n = 1;
            scanf("%d", &a[n]);
            if (a[n] == 0)
                break;
            while (a[n]) {
                n++;
                scanf("%d", &a[n]);
            }
            n--;
            memset(f, INF, sizeof(f));
            f[0][0][0] = 0;
            for (int i = 1; i <= n; i++) {
                for (int j = 0; j <= 4; j++) {
                    if (j != a[i]) {
                        if (a[i - 1] == j) {
                            for (int k = 0; k <= 4; k++)
                                if (k != a[i - 1] || i == 1) {
                                    f[i][j][a[i]] = min(f[i][j][a[i]], f[i - 1][j][k] + Count(k, a[i]));
                                    f[i][a[i]][j] = min(f[i][a[i]][j], f[i - 1][k][j] + Count(k, a[i]));
                                }
                        }
                        else {
                            f[i][j][a[i]] = min(f[i][j][a[i]], f[i - 1][j][a[i - 1]] + Count(a[i - 1], a[i]));
                            f[i][a[i]][j] = min(f[i][a[i]][j], f[i - 1][a[i - 1]][j] + Count(a[i - 1], a[i]));
                        }
                    }
                }
            }
            int res = INF;
            for (int i = 1; i <= 4; i++) {
                res = min(res, f[n][i][a[n]]);
                res = min(res, f[n][a[n]][i]);
            }
            printf("%d
    ", res);
        }
        return 0;
    }
  • 相关阅读:
    【LVS 】NAT方式实现过程
    【 LVS 】类型及算法
    [ 总结 ] RHEL6/Centos6 使用OpenLDAP集中管理用户帐号
    [ 手记 ] 关于tomcat开机启动设置问题
    [ 总结 ] nginx 负载均衡 及 缓存
    Mac
    Swift
    Swift
    Cocoapods
    Swift
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5249771.html
Copyright © 2020-2023  润新知