Codeforces Round #363 (Div. 1) A. Vacations(状态机 / 模拟)

https://codeforces.com/contest/698/problem/A

Vasya有n天假期!Vasya知道关于这n天中每一天的以下信息:那家健身房是否开门,以及那天是否在互联网中进行了比赛。第i天有四个选项:

0 这一天体育馆关闭,比赛也不进行;
1 这一天体育馆关闭,比赛开始;
2 这一天健身房开放,比赛不进行;
3 在这一天,体育馆开放,并进行比赛。
每一天Vasya可以休息或者写比赛(如果比赛在这一天进行),或者做运动(如果体育馆在这一天开放)。

找出Vasya休息的最少天数(这意味着,他不会同时做运动和写比赛)。Vasya的唯一限制是——他不想连续两天做同样的活动:这意味着,他不会连续两天做运动,连续两天写比赛。

简单的来说,题目意思就是n天中,他想最大化利用打比赛和运动的时间,问我们他在这n天中可以休息的时间是?

inputCopy
4
1 3 2 0
outputCopy
2
inputCopy
7
1 3 3 2 1 2 3
outputCopy
0
inputCopy
2
2 2
outputCopy
1
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const LL N=200200,M=200;
int a[N];
int dp[M][5];
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    int T=1;
    //cin>>T;
    while(T--)
    {
        int n;
        cin>>n;
        memset(dp,127,sizeof dp);
        //初始化没有开始的时候,休息时间都是为0的
        for(int i=0;i<=3;i++)
            dp[0][i]=0;
        for(int i=1;i<=n;i++)
            cin>>a[i];
        for(int i=1;i<=n;i++)
        {
            //当天的最小的值,默认是前一天的最小值+1
            dp[i][0]=min({dp[i-1][0],dp[i-1][1],dp[i-1][2]})+1;
            //cout<<dp[i][0]<<" ";
            //如果是1的话,就可以去0和2里面找,3可以转化成1
            if(a[i]==1||a[i]==3)
            {
                dp[i][1]=min(dp[i-1][0],dp[i-1][2]);
                //cout<<dp[i][1]<<" ";
            }
            //如果是2的话,就可以去0和1里面找,3可以转化成2
            if(a[i]==2||a[i]==3)
            {
                dp[i][2]=min(dp[i-1][0],dp[i-1][1]);
                //cout<<dp[i][2]<<" ";
            }
            //cout<<endl;
        }
        cout<<min({dp[n][0],dp[n][1],dp[n][2]})<<endl;
    }
    return 0;
}

另一种模拟写法

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N=200200,M=2002;
int a[N];
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    int T=1;
    //cin>>T;
    while(T--)
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
        }
        int sum=0;
        for(int i=1;i<=n;i++)
        {
            //昨天跟今天单项活动一样,必须摆一天
            if(a[i]==1&&a[i-1]==1) a[i]=0,sum++;
            else if(a[i]==2&&a[i-1]==2) a[i]=0,sum++;
            else if(a[i]==3)
            {
                //3 昨天干了啥,今天就换一种
                if(a[i-1]==1) a[i]=2;
                else if(a[i-1]==2) a[i]=1;
            }
            else if(a[i]==0) sum++;
            //0 没有活动不休息白不休息
        }
        cout<<sum<<endl;
    }
    return 0;
}
posted @ 2022-08-22 17:37  高尔赛凡尔娟  阅读(17)  评论(0编辑  收藏  举报