HDU 6379 Invoker (2019-CCPC-秦皇岛站)DP

Invoker

Time Limit: 15000/12000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 586    Accepted Submission(s): 100

 

Problem Description

在 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 表示,便可获得当前法球组合所对应的技能,同时原有的三个法球也不会消失,先后顺序的状态也不会改变。

现在给定一个技能序列,你想按照给定的顺序将他们一个一个地祈唤出来,同时你想用最少的按键来达到目标,所以你想知道对于给定的一个技能序列,最少按多少次键才能把他们都祈唤出来。

注意:游戏开始的时候,祈求者是没有任何法球的。

 

 

Input

仅一行一个字符串 s ,表示技能序列。其中所有字母都是大写,且在 {B,C,D,F,G,T,V,X,Y,Z} 内。

1≤|s|≤105

 

 

Output

仅一行一个正整数,表示最少按键次数。

 

 

Sample Input

 

XDTBV

 

 

Sample Output

 

14

Hint

一种按键最少的方案为:QWWREERERWQRQR

 

 

Source

 

642ccpcQHD

 

OJ题号

HDU 6379

简单题意

一个人有QWE三个基础技能,和一个大招R技能,每释放一个基础技能就会获得一个相应的技能点,最多同时拥有三个技能点,最早获得的技能点会被最新释放的技能点给挤走,每次释放R技能,就会根据现有的三个技能点的组合,释放出一个特殊技能,但是释放R技能不会消耗目前拥有的技能点。技能点组合对应的特殊技能名称如上图所示。现给出一列按时间顺序释放的特殊技能,问如何释放基础QWE技能以及R技能,使得释放的技能总数最小。
 

正解思路

我们可以知道当前技能释放需要增加按键数,是通过是一个技能决定的,关键看上一个技能含有当前技能的QWE有几个,我们知道总共就有36种状态,我们设dp[i][j]为当前为i个技能由第j种状态得来,具体看一下代码,一看就懂。

#include<bits/stdc++.h>
using namespace std;
#define maxn 105005
#define ll long long
map<char,string>mp;
int js(char x,int l1,int r1,char y,int l2,int r2)
{
    int sum=0;
    if(mp[x][l1]==mp[y][l2]&&mp[x][l1+1]==mp[y][l2+1]&&mp[x][l1+2]==mp[y][l2+2])
    {
        return 1;
    }
    else if(mp[x][l1+1]==mp[y][l2]&&mp[x][l1+2]==mp[y][l2+1])
        return 2;
    else if(mp[x][r1]==mp[y][l2])
        return 3;
    else
        return 4;
}
char c[maxn];
int dp[maxn][10];
int main()
{
    mp['Y'] = "1QQQQQQQQQQQQQQQQQQ";
    mp['V'] = "1QQWQWQWQQQQWQWQWQQ";
    mp['G'] = "1QQEQEQEQQQQEQEQEQQ";
    mp['C'] = "1WWWWWWWWWWWWWWWWWW";
    mp['X'] = "1QWWWQWWWQQWWWQWWWQ";
    mp['Z'] = "1WWEWEWEWWWWEWEWEWW";
    mp['T'] = "1EEEEEEEEEEEEEEEEEE";
    mp['F'] = "1QEEEQEEEQQEEEQEEEQ";
    mp['D'] = "1WEEEWEEEWWEEEWEEEW";
    mp['B'] = "1QWEQEWWEQWQEEQWEWQ";
    while(scanf("%s",c+1)!=EOF)
    {
        int n=strlen(c+1);
        for(int i=1;i<=6;i++)
            dp[1][i]=4;


        for(int i=2; i<=n; i++)
        {
            for(int j=1; j<=6; j++)
            {
                dp[i][j]=1e9;
            }
            for(int j=1; j<=6; j++)
            {
                for(int k=1; k<=6; k++)
                {
                    dp[i][j]=min(dp[i][j],dp[i-1][k]+js(c[i-1],(k-1)*3+1,k*3,c[i],(j-1)*3+1,j*3));
                }
            }
        }
        int ans=1e9;
        for(int i=1; i<=6; i++)
            ans=min(dp[n][i],ans);
        printf("%d\n",ans);
    }
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值