CCPC 2019秦皇岛 Invoker I题 hdu6739

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
char dict[10][6][4]= {                      //本题的状态与每个组合技能的顺序有关
	{"QQQ","QQQ","QQQ","QQQ","QQQ","QQQ"},      //直接枚举每个组合技能的顺序
	{"QQW","QWQ","QQW","QWQ","WQQ","WQQ"},
	{"QQE","QEQ","QQE","QEQ","EQQ","EQQ"},
	{"WWW","WWW","WWW","WWW","WWW","WWW"},
	{"QWW","QWW","WQW","WWQ","WQW","WWQ"},
	{"WWE","WEW","WWE","WEW","EWW","EWW"},
	{"EEE","EEE","EEE","EEE","EEE","EEE"},
	{"QEE","QEE","EQE","EEQ","EQE","EEQ"},
	{"WEE","WEE","EWE","EEW","EWE","EEW"},
	{"QWE","QEW","WQE","WEQ","EQW","EWQ"}
};

int dp[N][10];
int cal(int a,int b,int x,int y) { //a表示前一个状态(第a个状态)  a x表示第a个组合技第x种顺序
	//计算前后两种状态组合技需要多按几次按键
	if(dict[a][x][0]==dict[b][y][0] && dict[a][x][1] == dict[b][y][1] && dict[a][x][2]==dict[b][y][2])
		return 0;
	if(dict[a][x][1]==dict[b][y][0] && dict[a][x][2] == dict[b][y][1])
		return 1;
	if(dict[a][x][2]== dict[b][y][0])
		return 2;
	return 3;
}
map<char,int>mp;
int st[N];
int main() {
	string s;
	mp['Y']=0;
	mp['V']=1;
	mp['G']=2;
	mp['C']=3;
	mp['X']=4;
	mp['Z']=5;
	mp['T']=6;
	mp['F']=7;
	mp['D']=8;
	mp['B']=9;
	while(cin>>s) {
		int ans=2147483647;
		int cc=0;

		for(int i=0; i<s.length(); i++) {//若出现XXVV的情况 即前一个技能和本次技能一样则只需按一次R即可 把他处理成XV 
			if(cc>=1&&s[i]==s[i-1])
				continue;
			else {
				//	t+=s[i];
				st[cc]=mp[s[i]];
				cc++;
			}
		}
//	cout<<t<<"\n";
 //dp[i][j]的含义是 第i个组合技用了第j种方案的顺序 
		for(int i=0; i<6; i++) //该开始第一种方案都是直接需要三次按键来完成 
			dp[0][i]=3;
		for(int i=1; i<cc; i++) {
			for(int j=0; j<6; j++) {
				dp[i][j]=2147483647;
				for(int k=0; k<6; k++) {
					dp[i][j]=min(dp[i][j],dp[i-1][k]+cal(st[i-1],st[i],k,j));//枚举第i-1个状态的第k个方案的顺序操作 到第i个状态
					//第j个方案的操作数 
					  
				}
			}
		}

		for(int i=0; i<6; i++)//找到最优解 
			ans=min(ans,dp[cc-1][i]);
		cout<<ans+s.length()<<"\n";//每次组合技都需要按一次R 所以直接加上s的长度 
	}
}

参考了这位大佬的博客:https://blog.csdn.net/qq_43461168/article/details/101210999

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值