可以用动态解决问题,题目求的是最少的休息天数,我们可以通过求最大的工作天数来的得到答案。
用数组dp[ i ][ j ]记录到第 i 天为止Vasya最大的工作天数,j 的定义如下,
对于第 i 天 ,
• j=0,表示Vasya第 i 天休息,dp[ i ][0]就表示如果第 i 天休息的话,能得到的最大的工作天数(其它类似)。
• j=1 , 表示Vasya第 i 天参加contest。
• j=2 , 表示Vasya第 i 天去gym。
那么,可以得到下面的状态转移方程。
dp[ i ][ 0] =max( dp[ i-1 ][ j ] ), 0≤j≤2。
如果第 i 天有contest,即 ai=1或 ai=3,那么到第 i 天为止Vasya最大的工作天数为前一天Vasya休息或着去gym获得的最大的工作天数+1,即dp[ i ][1]=max( dp[i-1][0], dp[ i-1 ][2] ) + 1。
如果第 i 天gym开放,即 ai=2或 ai=3,那么到第 i 天为止Vasya最大的工作天数为前一天Vasya休息或着参加contest获得的最大的工作天数+1,即dp[ i ][1]=max( dp[i-1][0], dp[ i-1 ][1] ) + 1。
这样,最后的答案为n - max( dp[ n ][ j ] ), 0≤j≤2。
1 #include <iostream> 2 #include <algorithm> 3 #include <map> 4 #include <vector> 5 #include <functional> 6 #include <string> 7 #include <cstring> 8 #include <queue> 9 #include <stack> 10 #include <set> 11 #include <cmath> 12 #include <cstdio> 13 using namespace std; 14 #define IOS ios_base::sync_with_stdio(false) 15 #define TIE std::cin.tie(0) 16 #define MAX2(a,b) (a>b?a:b) 17 #define MAX3(a,b,c) (a>b?(a>c?a:c):(b>c?b:c)) 18 typedef long long LL; 19 typedef unsigned long long ULL; 20 const int INF=0x3f3f3f3f; 21 const double PI=4.0*atan(1.0); 22 23 int n,x,dp[105][3]; 24 int main() 25 { 26 while(~scanf("%d",&n)){ 27 memset(dp,0,sizeof(dp)); 28 for(int i=1;i<=n;i++){ 29 scanf("%d",&x); 30 dp[i][0]=MAX3(dp[i-1][0],dp[i-1][1],dp[i-1][2]); 31 if(x==1||x==3) dp[i][1]=MAX2(dp[i-1][0],dp[i-1][2])+1; 32 if(x==2||x==3) dp[i][2]=MAX2(dp[i-1][0],dp[i-1][1])+1; 33 } 34 printf("%d ",n-MAX3(dp[n][0],dp[n][1],dp[n][2])); 35 } 36 return 0; 37 }