Invoker(2019ccpc秦皇岛)

8 篇文章 0 订阅

Invoker

费了九牛二虎之力搞出来。
道路很曲折,代码写完了才发现一开始无脑屏蔽掉了出现数次的unordered,常识地以为是ordered 。

由于连招是无序的,并且三个连招只有六种排列组合,所以我们把每个连招可能的组合排列出来就可以转移状态了
dp[i][j] 表示:到第 i 位 选择 第 j 种连招所获得的最小代价。
所以每个 dp[i][j] 要从 第 i-1 位的 0 - 6 种 连招转移过来。

最后就是两个连招相邻连招的节约计算;

#include<bits/stdc++.h>

using namespace std;
const int N = 1e6+7;

int f[N][8];
string mp[200][10];

void init(){
mp['Y'][0] = "QQQ";
mp['Y'][1] = "QQQ";
mp['Y'][2] = "QQQ";
mp['Y'][3] = "QQQ";
mp['Y'][4] = "QQQ";
mp['Y'][5] = "QQQ";

mp['V'][0] = "QQW";
mp['V'][1] = "QQW";
mp['V'][2] = "QWQ";
mp['V'][3] = "QWQ";
mp['V'][4] = "WQQ";
mp['V'][5] = "WQQ";

mp['G'][0] = "QQE";
mp['G'][1] = "QQE"; 
mp['G'][2] = "QEQ"; 
mp['G'][3] = "QEQ"; 
mp['G'][4] = "EQQ";
mp['G'][5] = "EQQ"; 

mp['C'][0] = "WWW";
mp['C'][1] = "WWW";
mp['C'][2] = "WWW";
mp['C'][3] = "WWW";
mp['C'][4] = "WWW";
mp['C'][5] = "WWW";

mp['X'][0] = "QWW";
mp['X'][1] = "QWW"; 
mp['X'][2] = "WQW"; 
mp['X'][3] = "WQW"; 
mp['X'][4] = "WWQ"; 
mp['X'][5] = "WWQ"; 

mp['Z'][0] = "WWE";
mp['Z'][1] = "WWE";
mp['Z'][2] = "WEW";
mp['Z'][3] = "WEW";
mp['Z'][4] = "EWW";
mp['Z'][5] = "EWW";

mp['T'][0] = "EEE";
mp['T'][1] = "EEE"; 
mp['T'][2] = "EEE"; 
mp['T'][3] = "EEE"; 
mp['T'][4] = "EEE"; 
mp['T'][5] = "EEE"; 

mp['F'][0] = "QEE";
mp['F'][1] = "QEE";
mp['F'][2] = "EEQ";
mp['F'][3] = "EEQ";
mp['F'][4] = "EQE";
mp['F'][5] = "EQE";

mp['D'][0] = "WEE";
mp['D'][1] = "WEE";
mp['D'][2] = "EWE";
mp['D'][3] = "EWE";
mp['D'][4] = "EEW";
mp['D'][5] = "EEW";

mp['B'][0] = "QWE";
mp['B'][1] = "QEW";
mp['B'][2] = "WQE";
mp['B'][3] = "WEQ";
mp['B'][4] = "EWQ";
mp['B'][5] = "EQW";
}

int fun(string x,string y)
{
	if(x[0]==y[0]&&x[1]==y[1]&&x[2]==y[2]) return 1;
	if(x[1]==y[0]&&x[2]==y[1]) return 2;
	if(x[2]==y[0]) return 3;
	return 4;
}

int main()
{
	init();
	string s;
	while(cin>>s){
		s = '0' + s;
		int n = s.size();
		//cout<<s<<" "<<n<<"\n";
		for(int i=1;i<n;i++){
			for(int j=0;j<6;j++){
				if(i==1) f[i][j] = 4;
				else{
					f[i][j] = 1e9;
					for(int k=0;k<6;k++){
						f[i][j] = min(f[i-1][k] + fun (mp[s[i-1]][k] ,mp[s[i]][j] ), f[i][j] ) ;
					}
				}
			}
		}
	//	for(int i=0;i<n;i++){
	//		for(int j=0;j<6;j++) cout<<f[i][j]<<" ";
	//		cout<<"\n";
	//	}
		int ans = 1e9;
		for(int i=0;i<6;i++) ans = min(ans,f[n-1][i]);
		cout<<ans<<"\n";
	}
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值