一共有n天假期,每天假期对应四种编号对应多种可以选择的活动,问最少选择休息的天数:
0、只能休息
1、比赛或者休息
2、gym或者休息
3、gym或者比赛或者休息
除了休息可以两天连续做以外,任何两种活动不能同时两天去做。
思路:
1、基础Dp,设dp【i】【j】表示第i天,对应选择j方式去度过的情况下最少选择休息的天数;
dp【】【0】表示休息
dp【】【1】表示去gym
dp【】【2】表示去比赛
2、状态转移方程:
dp【】【0】=min(dp【i-1】【0-2】)+1;
dp【】【1】=min(dp【i-1】【0,2】);
dp【】【2】=min(dp【i-1】【0,1】);
Ac代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
int a[1000];
int dp[1000][4];
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++){scanf("%d",&a[i]);}
memset(dp,0x3f3f3f3f,sizeof(dp));
//0 xiuxi 1 gym 2 contest
dp[0][0]=1;
if(a[0]==1)
{
dp[0][2]=0;
}
if(a[0]==2)
{
dp[0][1]=0;
}
if(a[0]==3)
{
dp[0][1]=0;
dp[0][2]=0;
}
for(int i=1;i<n;i++)
{
if(a[i]==0)
{
for(int j=0;j<3;j++)
{
dp[i][0]=min(dp[i-1][j],dp[i][0]);
}
dp[i][0]+=1;
}
///////////
if(a[i]==1)
{
for(int j=0;j<3;j++)
{
if(j==2)continue;
dp[i][2]=min(dp[i-1][j],dp[i][2]);
}
for(int j=0;j<3;j++)
{
dp[i][0]=min(dp[i-1][j],dp[i][0]);
}
dp[i][0]+=1;
}
if(a[i]==2)
{
for(int j=0;j<3;j++)
{
if(j==1)continue;
dp[i][1]=min(dp[i-1][j],dp[i][1]);
}
for(int j=0;j<3;j++)
{
dp[i][0]=min(dp[i-1][j],dp[i][0]);
}
dp[i][0]+=1;
}
if(a[i]==3)
{
for(int j=0;j<3;j++)
{
if(j==1)continue;
dp[i][1]=min(dp[i-1][j],dp[i][1]);
}
for(int j=0;j<3;j++)
{
if(j==2)continue;
dp[i][2]=min(dp[i-1][j],dp[i][2]);
}
for(int j=0;j<3;j++)
{
dp[i][0]=min(dp[i-1][j],dp[i][0]);
}
dp[i][0]+=1;
}
}
int output=0x3f3f3f3f;
for(int i=0;i<3;i++)
{
output=min(output,dp[n-1][i]);
}
printf("%d\n",output);
}
}