2019ccpc秦皇岛/Gym102361 I - Invoker dp

题意:

连续3个特定的按键(在这3个中不要求顺序)能使出某个技能,使出不同技能所需要的按键可以重叠,给你一个技能序列,问你最少花费多少次按键能按顺序使出这些招数。

题解:

dp,dp[i][j]代表使出第i个技能后,最后3个按键组合是j的最少需要按键数,暴力枚举即可。

思路比较绕,实际码的时候很自闭。

#include<bits/stdc++.h>
using namespace std;
#define MAXN 100000+50
char s[MAXN];
string jineng[15][6]={
    {"QQQ","QQQ","QQQ","QQQ","QQQ","QQQ"},
    {"QQW","QQW","QWQ","QWQ","WQQ","WQQ"},
    {"QQE","QQE","QEQ","QEQ","EQQ","EQQ"},
    {"WWW","WWW","WWW","WWW","WWW","WWW"},
    {"QWW","QWW","WQW","WQW","WWQ","WWQ"},
    {"WWE","WWE","WEW","WEW","EWW","EWW"},
    {"EEE","EEE","EEE","EEE","EEE","EEE"},
    {"QEE","QEE","EQE","EQE","EEQ","EEQ"},
    {"WEE","WEE","EEW","EEW","EWE","EWE"},
    {"QWE","QEW","WEQ","WQE","EWQ","EQW"}
};
//CXZTFDB
int num[500];
int dp[MAXN][6];
int get_dif(int id1,int id2,int pos1,int pos2)
{
    if(jineng[id1][pos1][0]==jineng[id2][pos2][0]&&jineng[id1][pos1][1]==jineng[id2][pos2][1]
    &&jineng[id1][pos1][2]==jineng[id2][pos2][2])
    return 0;
    if(jineng[id1][pos1][1]==jineng[id2][pos2][0]&&jineng[id1][pos1][2]==jineng[id2][pos2][1])
    return 1;
    if(jineng[id1][pos1][2]==jineng[id2][pos2][0]) return 2;
    return 3;
}
int main()
{
    int ans;
    scanf("%s",s);
    int len=strlen(s);
    ans=len*3;
    memset(num,0,sizeof(num));
    num['Y']=0,num['V']=1,num['G']=2,num['C']=3,
    num['X']=4,num['Z']=5,num['T']=6,num['F']=7,
    num['D']=8,num['B']=9;
    for(int i=0;i<len;++i)
        for(int j=0;j<6;++j)
            dp[i][j]=len*3;
    for(int i=0;i<6;++i) dp[0][i]=3;
    for(int i=1;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]+get_dif(num[s[i-1]],num[s[i]],k,j));
            }
    for(int i=0;i<6;++i) ans=min(ans,dp[len-1][i]);
    cout<<ans+len<<endl; 
}

 

posted @ 2019-10-09 10:23  Isakovsky  阅读(302)  评论(0编辑  收藏  举报