HDU6739 Invoker dp
Posted yuanweidao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
以上是关于HDU6739 Invoker dp的主要内容,如果未能解决你的问题,请参考以下文章
HDU3247 Resource Archiver(AC自动机+BFS+DP)