小图有 n 天假期。他决定要提升一下自己的IT技能,同时还要健身。小图知道假期的每1天体育馆的开放信息和网络编程比赛信息。每1天都会有下面这4种可能性:
健身房关门,没有编程比赛。
健身房关门,有编程比赛。
健身房开门,没有编程比赛。
健身房开门,有编程比赛
每1天小图都可以选择是去健身(如果健身房开门)还是参加编程比赛(如果有比赛)。
请帮忙计算一下,整个假期下来,小图最少能休息多少天(不健身也不比赛)。小图唯一的一个规则就是,那就是不会连着2天健身或者连着2天参加编程比赛。
输入
第1行包含1个正整数 n (1 ≤ n ≤ 100) ——代表假期天数。
第1行包含用空格间隔的整数序列a1, a2, ..., an (0 ≤ ai ≤ 3) :
ai = 0, 第 i 天健身房关门且没有编程比赛。
ai = 1, 第 i 天健身房关门但有编程比赛。
ai = 2, 第 i 天健身房开门但没有编程比赛。
ai = 3, 第 i 天健身房开门且有编程比赛。
输出
输出小图最少能休息的天数。注意:
不能连着2天健身。
不能连着2天参加编程比赛。
样例
输入
4
1 3 2 0
输出
2
输入
7
1 3 3 2 1 2 3
输出
0
输入
2
2 2
输出
1
提示
第 1 个样例中,小图可以在第 1 天参加编程比赛,第 3 天去健身,因此他只有 2 天的休息时间。
第 2 个样例中,小图可以在第 1, 3, 5 , 7 天参加编程比赛,其他天都去健身,所以他没有一天可以休息。
第 3 个样例中,小图能在第1天或者第2天去健身,但不能连着 2 天健身,因此他只有 1 天的休息时间。
解题报告:这道题是dp题dp[i][j]代表0~i天最后一天是干j事情的最少休息天数。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=110;
int a[N];
int dp[N][3];
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
memset(dp,0x3f,sizeof dp);
dp[0][0]=1;
if(a[0]==1) dp[0][1]=0;
else if(a[0]==2) dp[0][2]=0;
else if(a[0]==3)
{
dp[0][1]=0;
dp[0][2]=0;
}
for(int i=1;i<n;i++)
{
dp[i][0]=min(dp[i-1][1]+1,min(dp[i-1][0]+1,dp[i-1][2]+1));//加if就错了,因为每天都可以选择休息
if(a[i]==1)
{
dp[i][1]=min(dp[i-1][0],dp[i-1][2]);//如果与前一天日子干的事情一样那么不合法应该休息一天就是前一天休息天数+1
}
else if(a[i]==2)
{
dp[i][2]=min(dp[i-1][0],dp[i-1][1]);
}
else if(a[i]==3)
{
dp[i][1]=min(dp[i-1][0],dp[i-1][2]);
dp[i][2]=min(dp[i-1][0],dp[i-1][1]);
}
}
cout<<min(dp[n-1][0],min(dp[n-1][1],dp[n-1][2]))<<endl;
}