seventh
CodeForces - 699C 两种做法:贪心和dp
题目:
给出n天,你知道每天体育馆有没有开放,测试有没有开放,让你判断最少休息的天数,你不能连续2天运动或者测试。
首先是dp做法:
每天需要判断三个决策:
1:休息 2:运动 3:测试
如果每天决策不同会影响答案,那么我们需要能够找出每天不同决策的最小答案。
用dp[i][0]记录如果今天是休息,那么今天为止的最少休息时间;
用dp[i][1]记录如果今天是运动,那么今天为止的最少休息时间;
用dp[i][2]记录如果今天是测试,那么今天为止的最少休息时间;
可以得出每个的状态转移方程
dp[i][0] = min(dp[i - 1][0], min(dp[i - 1][1], dp[i - 1][2])) + 1; 今天休息就不管昨天做什么,今天就等于昨天的最小值
dp[i][1] = min(dp[i - 1][2], dp[i - 1][0]); 今天运动,昨天只能休息或者测试,所以选择最小值
dp[i][2] = min(dp[i - 1][1], dp[i - 1][0]); 今天测试,昨天只能运动或者休息,选择它们之中的最小值
#include <iostream> #include<algorithm> using namespace std; int main(void) { int a[1000],dp[1000][3]; //dp表示i天最少休息多少次 int n, i; memset(dp, 100, sizeof(dp)); cin >> n; for (i = 1; i <= n; i++) { cin >> a[i]; } /*b[i][0]表示第i天休息时,目前为止最少的休息时间 * b[i][1]表示第i天运动时,目前为止最少的休息时间 * b[i][2]表示第i天测试时,目前为止最少的休息时间 */ dp[0][0]=0; //第一天之前可以看成什么都没做 for (i = 1; i<=n; i++) { //i从1开始,不用判断i-1,0-1是否越界 dp[i][0] = min(dp[i - 1][0], min(dp[i - 1][1], dp[i - 1][2])) + 1; //首先假使今天休息 if (a[i]==2||a[i]==3) { dp[i][1] = min(dp[i - 1][2], dp[i - 1][0]); //昨天休息或者测试 } if (a[i]==1 || a[i] == 3) { dp[i][2] = min(dp[i - 1][1], dp[i - 1][0]); //昨天休息或做运动 } /* 当是number3时,昨天可能做运动,可能测试,2者都要比较*/ } cout <<min(dp[n][0],min(dp[n][1],dp[n][2])); }
然后是贪心思路:直接判断每一天的情况,能不休息尽量不让他休息,分情况讨论一下~
#include <iostream> using namespace std; int a[105]; int ans; int main() { int n,i; cin>>n; for(i=1;i<=n;i++) cin>>a[i]; for(i=1;i<n;i++) { switch(a[i]) { case 0:{ans++;break;} case 1: { if(a[i+1]==1) a[i+1] = 0;//两天任务一样,就强制休息一天 if(a[i+1]==3) a[i+1] = 2;//为了让下一天不休息,就第二天只能做别的任务 break; } case 2: { if(a[i+1]==2) a[i+1] = 0; if(a[i+1]==3) a[i+1] = 1; break; } case 3: { break; } } } if(a[i]==0) ans++; cout << ans <<endl; //cout << "Hello world!" << endl; return 0; }

浙公网安备 33010602011771号