这里写一种与其他题解不一样的方法,简单易懂。
题目:
题目描述
小明正在玩一个“翻硬币”的游戏。
桌上放着排成一排的若干硬币。我们用 * 表示正面,用 o 表示反面(是小写字母,不是零)。
比如,可能情形是:oo*oooo
如果同时翻转左边的两个硬币,则变为:oooo***oooo
现在小明的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢?
我们约定:把翻动相邻的两个硬币叫做一步操作。
输入
两行等长的字符串,分别表示初始状态和要达到的目标状态。每行的长度< 1000
输出
一个整数,表示最小操作步数。
样例输入
ooo***
ooo***
样例输出
1
首先明确一件事:
贪心思想,每个位置要么变一次,要么不变。
设f[i][0]表示前i个变为相同所需最小次数,且[i,i+1]不翻转
f[i][1]表示前i个变为相同所需最小次数,且[i,i+1]翻转
当第i个位置不同时:
f[i][0]=f[i-1][1];因为第i个位置最终要相同,而[i,i+1]不变,那么[i-1,i]就要变
f[i][1]=f[i-1][0]+1; 第[i,i+1]变
当第i个位置相同时:
f[i][0]=f[i-1][0];
f[i][1]=f[i-1][1]+1;
最后f[n][0]就是答案。
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
char s1[1010],s2[1010];
int f[1010][2];
int main()
{
scanf("%s",s1+1);
scanf("%s",s2+1);
int len=strlen(s1+1);
for(int i=1;i<=len;i++)
{
if(s1[i]!=s2[i])
{
f[i][0]=f[i-1][1];
f[i][1]=f[i-1][0]+1;
}
else
{
f[i][0]=f[i-1][0];
f[i][1]=f[i-1][1]+1;
}
}
printf("%d",f[len][0]);
return 0;
}
本文介绍了一种解决翻硬币游戏问题的独特算法。通过贪心策略,文章详细阐述了如何计算从初始状态转变到目标状态所需的最小操作次数。利用动态规划的方法,定义了两种状态转移方程来实现这一计算。

9177

被折叠的 条评论
为什么被折叠?



