• HDU6739 Invoker 【dp】


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6739

    借鉴了这个网址的题解:https://blog.csdn.net/qq_41785863/article/details/101676640

    题意:每个大写字母代表一个技能,每个技能都由三个法球组成(无序的)。现在给出一串技能字符串,要求求出释放所有技能所需的最小按键次数、每输入一个法球按键一次,释放技能时需要按键一次(R)。

    思路:因为技能的组成是无序的,也就是每个技能有6种组合方式,可以全部枚举出来。后一个技能也可以全部枚举出来,这样找到相邻技能36种组合中,链接起来时,法球数目最少的。即可以得到我们的状态转移方程。

    dp[i][j]表示以j组合形式释放第i种技能时的最少按键次数。

    代码如下:

     1 #include<stdio.h>
     2 #include<iostream>
     3 #include<string.h>
     4 #include<string>
     5 #include<map>
     6 #include<algorithm>
     7 #define mem(a, b) memset(a, b, sizeof(a))
     8 const int MAXN = 1e5 + 10;
     9 const int inf = 0x3f3f3f3f;
    10 using namespace std;
    11 
    12 map<char, string> mp;
    13 char s[MAXN];
    14 int dp[MAXN][8];
    15 int dir[6][3] = {0, 1, 2,
    16                  0, 2, 1,
    17                  1, 0, 2,
    18                  1, 2, 0,
    19                  2, 0, 1,
    20                  2, 1, 0};
    21 
    22 int cal(string s, string s1, int x, int y)
    23 {
    24     int ret;
    25     if(s[dir[x][0]] == s1[dir[y][0]] && s[dir[x][1]] == s1[dir[y][1]] && s[dir[x][2]] == s1[dir[y][2]]) ret = 0;
    26     else if(s[dir[x][1]] == s1[dir[y][0]] && s[dir[x][2]] == s1[dir[y][1]]) ret = 1;
    27     else if(s[dir[x][2]] == s1[dir[y][0]]) ret = 2;
    28     else ret = 3;
    29     return ret;
    30 }
    31 
    32 int main()
    33 {
    34     mp['Y'] = "QQQ", mp['V'] = "QQW", mp['G'] = "QQE", mp['C'] = "WWW";
    35     mp['X'] = "QWW", mp['Z'] = "WWE", mp['T'] = "EEE", mp['F'] = "QEE";
    36     mp['D'] = "WEE", mp['B'] = "QWE";
    37     
    38     while(scanf("%s", s + 1) != EOF)
    39     {
    40         int len = strlen(s + 1);
    41         mem(dp, inf);
    42         for(int i = 0; i < 6; i ++)
    43             dp[1][i] = 4;
    44         for(int i = 2; i <= len; i ++)
    45             for(int j = 0; j < 6; j ++)
    46                 for(int k = 0; k < 6; k ++)
    47                     dp[i][j] = min(dp[i][j], dp[i - 1][k] + cal(mp[s[i - 1]], mp[s[i]], k, j) + 1); 
    48         int ans = inf;
    49         for(int i = 0; i < 6; i ++)
    50             ans = min(ans, dp[len][i]);
    51         printf("%d
    ", ans);
    52         }
    53     return 0;
    54 }
    View Code
  • 相关阅读:
    android
    需求分析
    请简述使用MediaRecorder实现录音的步骤
    AudioManager的详细内容
    ios 开发failed to chmod
    崩溃block
    图片不能切割成功 调了五个小时!!!!
    collectionView itemW宽度计算不对
    只用头文件
    ping 10.13.5.233
  • 原文地址:https://www.cnblogs.com/yuanweidao/p/11650016.html
Copyright © 2020-2023  润新知