zoukankan      html  css  js  c++  java
  • Invoker HDU

    题意:

    对于我这种不玩游戏的人来说,理解题目大意花了好久的时间。
    以下题目大意引用自此博客

    在 dota2 中有一个叫做祈求者(Invoker)的英雄,在游戏中他有三个基础技能:冰(Quas),雷(Wex),火(Exort),每施展一个技能就可以获得相应属性的一个法球(element)。
    但是祈求者同时最多只能有三个法球,即如果他在有三个法球的状态下又使用了某个法球技能,那么他会获得该法球,并失去之前三个法球中最先获得的一个。
    不难得出,祈求者身上的三个法球的无顺序组合有 10 种,每一种都对应着一个组合技能:

    1. 急速冷却(Cold Snap),无序组合 QQQ,用 Y 表示
    2. 幽灵漫步(Ghost Walk),无序组合 QQW,用 V 表示
    3. 寒冰之墙(Ice Wall),无序组合 QQE,用 G 表示
    4. 电磁脉冲(EMP),无序组合 WWW,用 C 表示
    5. 强袭飓风(Tornado),无序组合 QWW,用 X 表示
    6. 灵动迅捷(Alacrity),无序组合 WWE,用 Z 表示
    7. 阳炎冲击(Sun Strike),无序组合 EEE,用 T 表示
    8. 熔炉精灵(Forge Spirit),无序组合 QEE,用 F 表示
    9. 混沌陨石(Chaos Meteor),无序组合 WEE,用 D 表示
    10. 超震声波(Deafening Blast),无序组合 QWE,用 B 表示

    当祈求者拥有三个法球的时候,使用元素祈唤(Invoke)技能,用 R 表示,便可获得当前法球组合所对应的技能,同时原有的三个法球也不会消失,先后顺序的状态也不会改变。
    现在给定一个技能序列,你想按照给定的顺序将他们一个一个地祈唤出来,同时你想用最少的按键来达到目标,所以你想知道对于给定的一个技能序列,最少按多少次键才能把他们都祈唤出来。
    注意:游戏开始的时候,祈求者是没有任何法球的。

    分析:

    首先确定状态,因为序列是无序的,所以对于要产生的一个字符,有6种对应的组合(假设所有的字符均不相同)。
    (dp[i][j]):表示产生序列中第 (i) 个位置的字符对应的第 (j) 中序列所需的操作数。
    状态转移方程:(dp[i][j]=min(dp[i][j],dp[i-1][k]+cal(ss[i],ss[i-1],j,k)+1);)
    其中 (cal()),表示通过对比产生第 (i)(i-1) 位置的字符对应的第 (j) 和 第 (k) 种序列的差别,来确定操作的次数。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e5+5;
    const int inf=0x3f3f3f3f;
    char ss[N];
    int dp[N][7],p[6][3]={0,1,2,0,2,1,1,0,2,1,2,0,2,1,0,2,0,1};//序列位置的排列方式
    map<char,string>mp;
    void init()
    {
        mp['Y']="QQQ";
        mp['V']="QQW";
        mp['G']="QQE";
        mp['C']="WWW";
        mp['X']="QWW";
        mp['Z']="WWE";
        mp['T']="EEE";
        mp['F']="QEE";
        mp['D']="WEE";
        mp['B']="QWE";
    }
    int cal(char c1,char c2,int x,int y)
    {//注意比较的位置
        string s=mp[c1];
        string t=mp[c2];
        if(s[p[x][0]]==t[p[y][0]]&&s[p[x][1]]==t[p[y][1]]&&s[p[x][2]]==t[p[y][2]])
            return 0;
        else if(s[p[x][0]]==t[p[y][1]]&&s[p[x][1]]==t[p[y][2]])
            return 1;
        else if(s[p[x][0]]==t[p[y][2]])
            return 2;
        else return 3;
    }
    int main()
    {
        init();
        while(scanf("%s",ss+1)!=EOF)
        {
            int len=strlen(ss+1);
            memset(dp,inf,sizeof(dp));
            for(int i=0;i<6;i++) dp[1][i]=4;
            for(int i=2;i<=len;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]+cal(ss[i],ss[i-1],j,k)+1);
                }
            }
            int ans=inf;
            for(int i=0;i<6;i++)
                ans=min(ans,dp[len][i]);
            printf("%d
    ",ans);
        }
        return 0;
    }
    
    
  • 相关阅读:
    分支管理和自动化部署需求
    swiper 的左右箭头放到外面
    使用Foxmail登录阿里企业邮箱(钉钉邮箱)
    正则表达式 把所有的花引号替换为直引号 把字符串中所有单词的首字母都转换为大写
    react中getDerivedStateFromProps和componentDidUpdate配合使用
    model进阶
    cooke和session
    Django基础四之模板系统
    Django基础三之视图函数
    Django基础二之URL路由系统
  • 原文地址:https://www.cnblogs.com/1024-xzx/p/12991711.html
Copyright © 2011-2022 走看看