zoukankan      html  css  js  c++  java
  • 2019CCPC秦皇岛 I Invoker

    题意:

    就是魔法召唤技能,最少的符号数之类的。

    思路:

    线性dp题

    记 dp[i][6] 为祈唤出第 i 个技能之后,身上三个法球的先后顺 序为 0 ∼ 5 的状态的最少按键数。(就是一种技能的三个发球的排列总数为6)

    转移就暴力枚举上一个技能的结尾状态,然后算一下有几个 法球是可以重复使用的,取个最优值就行了。

    预处理一下第i种技能的排列为z1的时候转移到第j种技能状态为z2需要的步数数组dis

    写一下全排列,然后多写函数结构化程序,实现也是较为简单的。

    代码:

    #define _CRT_SECURE_NO_WARNINGS
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int N = 2e5 + 10;
    int dis[10][10][6][6];
    const int INF = 0x3f3f3f3f;
    ll dp[N][6];
    int get_id(char ch) {
        if (ch == 'Y')return 0;
        if (ch == 'V')return 1;
        if (ch == 'G')return 2;
        if (ch == 'C')return 3;
        if (ch == 'X')return 4;
        if (ch == 'Z')return 5;
        if (ch == 'T')return 6;
        if (ch == 'F')return 7;
        if (ch == 'D')return 8;
        if (ch == 'B')return 9;
    }
    string str[10] = { "QQQ","QQW","QQE","WWW","QWW","WWE","EEE","QEE","WEE","QWE" };
    string get_string(int id, int num) {
        string s = str[id];
        string ans;
        int p[3] = { 0,1,2};
        int cnt = 0;
        do {
            if (cnt++ == num) {
                //ans=str[id][0]+str[id][1] + str[id][2];
                ans.push_back(str[id][p[0]]);
                ans.push_back(str[id][p[1]]);
                ans.push_back(str[id][p[2]]);
                return ans;
            }
        }while(next_permutation(p, p + 3));
    }
    int get_val(string s1, string s2) {
        if (s1 == s2)return 0;
        if (s1[1] == s2[0] && s1[2] == s2[1])return 1;
        if (s1[2] == s2[0])return 2;
        return 3;
    }
    void init(){
        string s1, s2;
        for(int i=0;i<10;i++)
            for (int j = 0; j < 10; j++) {
                for(int z1=0;z1<6;z1++)
                    for (int z2 = 0; z2 < 6; z2++) {
                        s1 = get_string(i, z1); s2 = get_string(j, z2);
                        dis[i][j][z1][z2] = get_val(s1, s2);
                    }
            }
    }
    char s[N];
    int n;
    int main() {
        while (~scanf("%s", &s)) {
    //(hdu上面必须加多组输入)
            n = strlen(s);
            for (int i = 1; i < n; i++)
                for (int j = 0; j < 6; j++)
                    dp[i][j] = INF;
            init();
            for (int i = 0; i < 6; i++)dp[0][i] = 4;
            int id1, id2;
            for (int i = 1; i < n; i++) {
                id1 = get_id(s[i - 1]); id2 = get_id(s[i]);
                for (int j = 0; j < 6; j++)
                    for (int k = 0; k < 6; k++) {
                        dp[i][j] = min(dp[i][j], dp[i - 1][k] + dis[id1][id2][k][j] + 1);
                    }
            }
            ll ans = dp[n - 1][0];
            for (int i = 1; i < 6; i++) {
                ans = min(ans, dp[n - 1][i]);
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }
    不疯魔不成活
  • 相关阅读:
    Delphi 2005 以上版本GIF动画播放设置
    WIN7中盾牌的编程-DELPHI
    Delphi中ComPort通信中的数据处理
    【ZJOI2008】树的统计(树链剖分)
    【CJOJ2440】大话西游(树链剖分)
    【洛谷3384】【模板】树链剖分
    【NOI2004】郁闷的出纳员(splay)
    【HNOI2004】宠物收养所(splay)
    【HNOI 2002 】营业额统计(splay)
    【Tyvj 1728】普通平衡树
  • 原文地址:https://www.cnblogs.com/gzr2018/p/11605385.html
Copyright © 2011-2022 走看看