题目链接:C. Vacations
题意:现在有n天的假期,对于第i天有四种情况:
0 gym没开,contest没开
1 gym没开,contest开了
2 gym开了,contest没开
3 gym开了,contest开了
所有题主每天可能就有三种选择,rest,do sport,do contest。题主拒绝连续两天做同样的事情。现在请你安排他的假期,使得题主休息的天数最少。
思路:tag:dp
n=100的dp和暴力有什么区别... ...
第i天的三种选择得到的最少休息天数,只需要知道第i-1天的对应(活动不重复)选择得到的最少休息天数。
感觉这种dp初始化比状态转移方程还要麻烦~~~
#include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> #include<map> #include<queue> #include<iostream> #include<vector> #define maxn 210 #define inf 9999999 using namespace std; ///不能连续做两天一样的活动 安排使其休息最少的天数 问最少休息的天数 int val[maxn]; int dp[maxn][5]; /// 0 rest 1 sport 2 contest int main() { // freopen("in.cpp", "r", stdin); int n; while(~scanf("%d", &n)) { for (int i=1; i<=n; ++i) { scanf("%d", &val[i]); } for (int i=1; i<=n; ++i) { dp[i][0] = inf; dp[i][1] = inf; dp[i][2] = inf; } dp[1][0] = 1; if (val[1] == 2 || val[1] == 3) { dp[1][1] = 0; } if (val[1] == 1 || val[1] == 3) { dp[1][2] = 0; } for (int i=2; i<=n; ++i) { dp[i][0] = min(dp[i-1][0], min(dp[i-1][1], dp[i-1][2]))+1; if (val[i] == 2 || val[i] == 3) { dp[i][1] = min(dp[i-1][0], dp[i-1][2]); } if (val[i] == 3 || val[i] == 1) { dp[i][2] = min(dp[i-1][1], dp[i-1][0]); } } int ans = min(dp[n][0], min(dp[n][1], dp[n][2])); printf("%d\n", ans); } return 0; }