codeforces 698A. Vacations
传送门儿
题目大意:给一个序列限制条件(体育馆开放与否、考试与否),问你这n天最少有几天闲着。
方法:dp。
分析:每天对应三种状态:闲着、锻炼、考试。
定义状态:dp[i][0]闲着 dp[i][1]锻炼 dp[i][2]考试
dp表示i天前最多能有几天不闲着(最后用n-不闲着的天数就ok)
每个状态的转移有条件限制:
0休息:无条件 (易错,休息的条件并不是0,因为哪天都能休息)
1锻炼:2 || 3
2考试:1 || 3
补充:codeforces1195C这道题每个i也是三种状态,不一样的是,这道题每种状态转移不需要条件,而本题每种状态转移需要条件!
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
int main()
{
int n;
scanf("%d",&n);
int a[200];
int dp[200][5];
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
{
dp[i][0]=max(dp[i-1][0],max(dp[i-1][1],dp[i-1][2]));
//dp[i][1]=dp[i-1][1];
//dp[i][2]=dp[i-1][2];
if(a[i]==1 || a[i]==3)
dp[i][2]=max(dp[i-1][2],(max(dp[i-1][0],dp[i-1][1])+1));
if(a[i]==2 || a[i]==3)
dp[i][1]=max(dp[i-1][1],(max(dp[i-1][0],dp[i-1][2])+1));
/*
else
{
if(a[i]==2)
{
dp[i][1]=max(dp[i-1][1],(max(dp[i-1][0],dp[i-1][2])+1));
//dp[i][0]=dp[i-1][0];
//dp[i][2]=dp[i-1][2];
}
if(a[i]==1)
{
dp[i][2]=max(dp[i-1][2],(max(dp[i-1][0],dp[i-1][1])+1));
//dp[i][0]=dp[i-1][0];
// dp[i][1]=dp[i-1][1];
}
if(a[i]==3)
{
dp[i][1]=max(dp[i-1][1],(max(dp[i-1][0],dp[i-1][2])+1));
dp[i][2]=max(dp[i-1][2],(max(dp[i-1][0],dp[i-1][1])+1));
//dp[i][0]=dp[i-1][0];
}
}
*/
//cout<<"a[i]: "<<a[i]<<" ";
//cout<<"dp0: "<<dp[i][0]<<" "<<" dp1: "<<dp[i][1]<<" dp2: "<<dp[i][2]<<endl;
}
cout<<n-max(dp[n][0],max(dp[n][1],dp[n][2]))<<endl;
return 0;
}
/*
100
3 2 3 3 3 2 3 1 3 2 2 3 2 3 3 3 3 3 3 1 2 2 3 1 3 3 2 2 2 3 1 0 3 3 3 2 3 3 1 1 3 1 3 3 3 1 3 1 3 0 1 3 2 3 2 1 1 3 2 3 3 3 2 3 1 3 3 3 3 2 2 2 1 3 1 3 3 3 3 1 3 2 3 3 0 3 3 3 3 3 1 0 2 1 3 3 0 2 3 3
*/