seventh

CodeForces - 699C  两种做法:贪心和dp

题目:

给出n天,你知道每天体育馆有没有开放,测试有没有开放,让你判断最少休息的天数,你不能连续2天运动或者测试。

 

首先是dp做法:

 

每天需要判断三个决策:

1:休息  2:运动    3:测试

如果每天决策不同会影响答案,那么我们需要能够找出每天不同决策的最小答案。

用dp[i][0]记录如果今天是休息,那么今天为止的最少休息时间;

用dp[i][1]记录如果今天是运动,那么今天为止的最少休息时间;

用dp[i][2]记录如果今天是测试,那么今天为止的最少休息时间;

可以得出每个的状态转移方程

dp[i][0] = min(dp[i - 1][0], min(dp[i - 1][1], dp[i - 1][2])) + 1;    今天休息就不管昨天做什么,今天就等于昨天的最小值

dp[i][1] = min(dp[i - 1][2], dp[i - 1][0]);    今天运动,昨天只能休息或者测试,所以选择最小值

dp[i][2] = min(dp[i - 1][1], dp[i - 1][0]);   今天测试,昨天只能运动或者休息,选择它们之中的最小值

#include <iostream>
#include<algorithm>
using namespace std;
 
int main(void)
{
    int a[1000],dp[1000][3]; //dp表示i天最少休息多少次
    int n, i;
    memset(dp, 100, sizeof(dp));
    cin >> n;
    for (i = 1; i <= n; i++) {
        cin >> a[i];
    }
/*b[i][0]表示第i天休息时,目前为止最少的休息时间
* b[i][1]表示第i天运动时,目前为止最少的休息时间
* b[i][2]表示第i天测试时,目前为止最少的休息时间
*/
    dp[0][0]=0;  //第一天之前可以看成什么都没做
    for (i = 1; i<=n; i++) { //i从1开始,不用判断i-1,0-1是否越界
        dp[i][0] = min(dp[i - 1][0], min(dp[i - 1][1], dp[i - 1][2])) + 1;  //首先假使今天休息
        if (a[i]==2||a[i]==3) {
            dp[i][1] = min(dp[i - 1][2], dp[i - 1][0]);  //昨天休息或者测试
        }
        if (a[i]==1 || a[i] == 3) {
            dp[i][2] = min(dp[i - 1][1], dp[i - 1][0]);  //昨天休息或做运动
        }
        /* 当是number3时,昨天可能做运动,可能测试,2者都要比较*/
    }
    cout <<min(dp[n][0],min(dp[n][1],dp[n][2]));
}

 

然后是贪心思路:直接判断每一天的情况,能不休息尽量不让他休息,分情况讨论一下~

 

#include <iostream>

using namespace std;
 
int a[105];
int ans;
 
int main()
{
    int n,i;
    cin>>n;
    for(i=1;i<=n;i++)
        cin>>a[i];
    for(i=1;i<n;i++)
    {
        switch(a[i])
        {
            case 0:{ans++;break;}
            case 1:
                {
                    if(a[i+1]==1)
                        a[i+1] = 0;//两天任务一样,就强制休息一天
                    if(a[i+1]==3)
                        a[i+1] = 2;//为了让下一天不休息,就第二天只能做别的任务
                    break;
                }
            case 2:
                {
                    if(a[i+1]==2)
                        a[i+1] = 0;
                    if(a[i+1]==3)
                        a[i+1] = 1;
                    break;
                }
            case 3:
                {
                    break;
                }
        }
    }
    if(a[i]==0)
        ans++;
    cout << ans <<endl;
    //cout << "Hello world!" << endl;
    return 0;
}

 

posted @ 2021-02-23 14:09  彦辰kkkkk  阅读(165)  评论(0)    收藏  举报