题意:字面意思。。。
分析:可以考虑贪心,每次考虑最优,同优的情况往后走看走哪个会返回原来的出发点。
也可以考虑动规。用dp[i][j][k]表示第k次操作时左手在i 右手在j时所消耗的能量。
dp[i][j][k]=Min(dp[t][j][k-1]+w[t][i],dp[i][t][k-1]+w[t][j]);
//贪心
#include<cstdio>
#include<algorithm>
#include<cstring>
#define MAX_S 1000005
using namespace std;
int w[4][4]={{0,1,2,2},{1,0,1,1},{2,1,0,2},{2,1,2,0}};
char str[MAX_S+100];
int main(void)
{
while(scanf("%s",str)==1)
{
int st1=2,st2=3;
int len=strlen(str);
int sum=0;
for(int i=0;i<len;i++)
{
if(w[st1][str[i]-'0']<w[st2][str[i]-'0'])
{
sum+=w[st1][str[i]-'0'];
st1=str[i]-'0';
}
else if(w[st1][str[i]-'0']>w[st2][str[i]-'0'])
{
sum+=w[st2][str[i]-'0'];
st2=str[i]-'0';
}
else
{
int j;
for(j=i+1;j<len;j++)
{
if(str[j]-'0'==st1||str[j]-'0'==st2)
break;
}
if(str[j]-'0'==st2)
{
sum+=w[st1][str[i]-'0'];
st1=str[i]-'0';
}
else
{
sum+=w[st2][str[i]-'0'];
st2=str[i]-'0';
}
}
}
printf("%d\n",sum);
}
return 0;
}
//DP
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define MAX_S 1000005
#define inf 0x3f3f3f3f
using namespace std;
char str[MAX_S];
int dp[MAX_S][4][4];
int w[4][4]={0,1, 2, 2 , 1 ,0 ,1, 1 , 2, 1 ,0 ,2 , 2 ,1 ,2 ,0};
int main(void)
{
while(scanf("%s",str)!=EOF)
{
int len=strlen(str);
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
dp[i][j][0]=w[2][i]+w[3][j];
}
for(int k=1;k<=len;k++)
{
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
dp[i][j][k]=min(dp[str[k-1]-'0'][j][k-1]+w[str[k-1]-'0'][i],dp[i][str[k-1]-'0'][k-1]+w[str[k-1]-'0'][j]);
}
}
int ans=inf;
for(int i=0;i<4;i++)
{
ans=min(ans,dp[i][str[len-1]-'0'][len]);
ans=min(ans,dp[str[len-1]-'0'][i][len]);
}
printf("%d\n",ans);
}
return 0;
}