题目描述:题目链接
题目分析:坐标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]));
}
}