码迷,mamicode.com
首页 > 其他好文 > 详细

2019CCPC秦皇岛 I Invoker

时间:2019-09-28 23:30:04      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:next   war   class   秦皇岛   string   思路   eee   turn   c++   

题意:

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

思路:

线性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\n", ans);
    }
    return 0;
}

 

2019CCPC秦皇岛 I Invoker

标签:next   war   class   秦皇岛   string   思路   eee   turn   c++   

原文地址:https://www.cnblogs.com/gzr2018/p/11605385.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!