刷题第5天-Lintcode267.最短休息日

题目描述:题目链接


题目分析:坐标DP

(1)要么休息,要么上班,要么健身,除了休息前一天不能干相同的。

(2)开一个数组dp[n][3],分别代表

dp[i][0] :代表第i天休息时,此时最少休息的天数

dp[i][1]:代表第i天上班时,此时最少休息的天数

dp[i][2]:代表第i天健身时,此时最少休息的天数。

我的错误点:数组要赋值一个大于情况的初始值,因为有的位置填不了数(由于公司或健身房不开门,此时这个位置就不填数字)

(3)给第0天的赋值,dp[0][0] = 1, dp[0][1]=1 or 0(公司开门就为0),dp[0][2] = 1 or 0(健身房开门就为0,不开就为1)

(4)开始遍历从第0天到第n-1天。

当第i天为休息,则从i-1天选一个最小的数+新的休息天数,则:dp[i][0] = 1 + Math.min(dp[i-1][0],Math.min(dp[i-1][1],dp[i-1][2]));

当第i天为上班,则从i-1天健身房(开门再选)和休息天数里面选。

当第i天为健身,则从i-1天公司(开门再选)和休息天数里面选。

(5)最后取第dp[n-1][0-2]中最小的数即可

public class Solution {
    /**
     * @param company: Company business
     * @param gym: Gym business
     * @return: Find the shortest rest day
     */
    public int minimumRestDays(List<Integer> company, List<Integer> gym) {
        // write your code here
        int n = company.size();
        int[][] dp = new int[n][3];
        //dp[i][0]代表第i天为休息时最小休息天数,dp[i][1]代表第i天上班,dp[i][2]代表第i天健身
        for (int[] row : dp) {
            Arrays.fill(row, n);
        }

        dp[0][0] = 1;
        if(company.get(0)==1)
            dp[0][1] = 0;
        else
            dp[0][1] = 1;
        
        if(gym.get(0)==1)
            dp[0][2] = 0;
        else
            dp[0][2] = 1;
      

        //开始遍历
        for(int i=1;i<n;i++)//第i天
        {
            //第i天休息
            dp[i][0] = 1 + Math.min(dp[i-1][0],Math.min(dp[i-1][1],dp[i-1][2]));

            //第i天上班
            if(company.get(i)==1)
            {
                dp[i][1] = dp[i-1][0];//休息
                if(gym.get(i-1)==1)//前一天健身房开门,可以健身
                    dp[i][1] = Math.min(dp[i][1],dp[i-1][2]);
            }
                

            //第i天健身
            if(gym.get(i)==1)
            {
                dp[i][2] = dp[i-1][0];
                if(company.get(i-1)==1)
                    dp[i][2] = Math.min(dp[i][2],dp[i-1][1]);

            }
                
            
        }

        for(int i=0;i<n;i++)
        {
            for(int j=0;j<3;j++)
            {
                System.out.print(dp[i][j]+" ");
            }
            System.out.println();
        }

        return Math.min(dp[n-1][0],Math.min(dp[n-1][1],dp[n-1][2]));

    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值