Description:
瓦西亚有n天的假期!所以他决定提高自己的IT技能并做运动。Vasya知道以下关于这n天的每一天的信息:该健身房是否开放以及当天是否在互联网上进行了比赛。第i天有四种选择:
在这一天,健身房关闭,比赛没有进行;
在这一天,健身房关闭,比赛进行;
在这一天,健身房开放,比赛没有进行;
在这一天,健身房开放,比赛进行。
在每一天,Vasya可以休息或写比赛(如果在这一天进行),或者做运动(如果健身房在这一天开放)。
找出Vasya休息的最少天数(这意味着他不会做运动并同时写比赛)。Vasya唯一的限制 - 他不想连续两天做同样的活动:这意味着,他不会连续两天做运动,连续两天写比赛。
Analysis
f[i][j] := 第i天做第j件事 (0: rest,1: contest,2:gym)
a[i] = 0,只能休息
a[i] = 1,休息 或 比赛
a[i] = 2,休息 或 运动
a[i] = 3,休息 或 运动 或 比赛
Code
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 110
using namespace std;
// 0:rest 1:contest 2:sport
int a[N],f[N][3],n;
int main()
{
scanf("%d",&n);
for(int i = 1;i <= n;++i)
{
scanf("%d",&a[i]);
}
memset(f,0x3f,sizeof(f));
f[1][0] = 1;
if(a[1] == 1) f[1][1] = 0;
if(a[1] == 2) f[1][2] = 0;
if(a[1] == 3)
{
f[1][1] = f[1][2] = 0;
}
for(int i = 2;i <= n;++i)
{
f[i][0] = min(f[i-1][0],min(f[i-1][1],f[i-1][2])) + 1;
// 前一天休息加今天比赛, 前一天运动加今天比赛, 前一天比赛加今天休息
if(a[i] == 1) f[i][1] = min(f[i-1][0],min(f[i-1][2],f[i-1][1] + 1));
// 前一天休息加今天运动, 前一天比赛加今天运动, 前一天运动加今天休息
if(a[i] == 2) f[i][2] = min(f[i-1][0],min(f[i-1][1],f[i-1][2] + 1));
if(a[i] == 3)
{
f[i][1] = min(f[i-1][0],min(f[i-1][2],f[i-1][1] + 1));
f[i][2] = min(f[i-1][0],min(f[i-1][1],f[i-1][2] + 1));
}
}
printf("%d
",min(f[n][0],min(f[n][1],f[n][2])));
return 0;
}