现在的位置: 首页 > 综合 > 正文

soj2818: QQ音速

2019年11月08日 ⁄ 综合 ⁄ 共 1546字 ⁄ 字号 评论关闭

Description

最近flymouse开始玩qq音速,这个游戏只需要按4个键,上,下,左,右(分别用u,d,l,r表示)。 flymouse必须按照游戏规则,依次按下一系列键。问题是flymouse的手太胖了,他只能把两个手指放在方向键上。 flymouse把一个手指从键i移动到键j,要耗费w[i][j]的体力,而按键不需要耗费体力。 由于flymouse反应比较慢,所以他每次只能移动一个手指。现在可怜的flymouse问你,他最少耗费多少体力? 假设flymouse一开始就把手指放在左、右两个键上。 下面是w[i][j]数组 u d l r u 0 1 2 2 d 1 0 1 1 l 2 1 0 2 r 2 1 2 0

Input

本题有多组测试数据,请处理到EOF 每组数据仅一行,为一个仅由0,1,2,3组成的串,表示flymouse需要依次按下的键 串的长度不超过10^6 0,1,2,3 分别代表 u,d,l,r

Output

对每组输入,输出flymouse耗费的最少体力

Sample Input

01230123

Sample Output

8

Source

Felicia @ WHU

dp[i][x][y]:从第i步,两根手指分别在x,y上时,走到最后,代价是多少

由于1e6太大会爆炸,有因为i的状态只由i+1推出,所以,滚动即可

#include<map>
#include<string>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<vector>
#include<iostream>
#include<algorithm>
#include<bitset>
#include<climits>
#include<list>
#include<iomanip>
#include<stack>
#include<set>
using namespace std;
int dp[2][4][4];
int w[4][4]={0,1,2,2,1,0,1,1,2,1,0,2,2,1,2,0};
int main()
{
	string s;
	while(cin>>s)
	{
		int n=s.length();
		s="0"+s;
		memset(dp,127,sizeof(dp));
		for(int i=0;i<4;i++)
			if(i!=s[n]-'0')
				dp[n&1][s[n]-'0'][i]=dp[n&1][i][s[n]-'0']=0;
		for(int i=n-1;i>0;i--)
		{
			int x=s[i]-'0',y=s[i+1]-'0',k=i+1;
			for(int j=0;j<4;j++)
			{
				if(j==x)
					continue;
				dp[i&1][j][x]=dp[i&1][x][j]=INT_MAX;
				dp[i&1][j][x]=min(dp[i&1][j][x],dp[k&1][j][y]+w[x][y]);
				dp[i&1][j][x]=min(dp[i&1][j][x],dp[k&1][y][x]+w[j][y]);
				dp[i&1][x][j]=min(dp[i&1][x][j],dp[k&1][y][j]+w[x][y]);
				dp[i&1][x][j]=min(dp[i&1][x][j],dp[k&1][x][y]+w[j][y]);
			}
		}
		dp[0][2][3]=INT_MAX;
		dp[0][2][3]=min(dp[0][2][3],dp[1][s[1]-'0'][3]+w[2][s[1]-'0']);
		dp[0][2][3]=min(dp[0][2][3],dp[1][2][s[1]-'0']+w[3][s[1]-'0']);
		cout<<dp[0][2][3]<<endl;
	}
}

抱歉!评论已关闭.