题意:Farmer John有两颗苹果树,分别编号为1和2,每棵树上都长满了苹果,Bessie无法摘到树上的苹果,所以只能等待苹果掉下来,厉害的是Bessie每次都能在苹果碰到地之前接住苹果,但前提是Bessie必须当前时刻在这颗树的下方,已知每分钟都有一颗树会掉落一个苹果,Bessie初始位置在第1颗树。现给出一个T代表总时间,W代表Bessie可以移动的次数,即从一颗树到另一颗树算移动一次。
7 2
2
1
1
2
2
1
1
6
数据解释: 一共有7分钟, 最多可以移动2次,第1分钟第2颗树掉落苹果,第2分钟第1颗树掉落苹果,第3分钟第1颗树掉落苹果,第4分钟第2颗树掉落苹果,第5分钟第2颗树掉落苹果,第6分钟第1颗树掉落苹果,第7分钟第1颗树掉落苹果。
Bessie在第1分钟不移动,依旧待在第1颗树,所以他可以接住第2,3分钟掉落的苹果,之后再第4分钟他移动到第2颗数,在第4分钟和第5分钟接住第2颗树掉落的苹果,之后再移动回第一颗树,接住最后两个苹果。
题解:我第一次做想着是一共有三个变量 时间,移动次数,树,所以我直接开了d[T][W][3]三维数组记录状态,d[T][W][1]代表在T时间,还剩下W次移动状态下到第1颗树时接住的总苹果树,d[T][W][2]就代表着第2颗树。
状态转移方程:
如果 w-1 >= 0
d[T][W][1] = max(d[T-1][W-1][2],d[T-1][W][1])
d[T][W][2] = max(d[T-1][W-1][1],d[T-1][W][2])
否则 d[T][W][1] = d[T-1][W][1];
如果a[i] == 1 d[T][W][1]++;
如果a[i] == 2 d[T][W][2]++;
初始化: T = 0时,肯定没有苹果可以接所以是0。
第二种解法:
可以省略掉第三维,仔细观察移动次数和树的关系,我们可以发现如果移动偶数次那么肯定还是在1号树,移动奇数次就是在2号树(因为初始在1号树)
所以在判断是否要++的时候可以用总w-当前剩余次数 = 移动的次数cnt。
cnt%2 +1 == a[i] 的话就说明此时有苹果可接,d[t][w]++。
贴一发第一次写的戳代码:
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int a[1010];
int d[1010][40][3];
int main(){
int t,w;
cin >> t >> w;
for(int i = 1; i <= t; ++i)
cin >> a[i];
memset(d,0,sizeof(d));
for(int i = 1; i <= t; ++i){
for(int j = 0; j <= w; ++j){
if(a[i] == 1){
int t = -1, t2 = -1;
if(j-1 >= 0){
d[i][j][1] = max(d[i-1][j][1]+1,d[i-1][j-1][2]);
d[i][j][2] = max(d[i-1][j][2],d[i-1][j-1][1]+1);
}
else{
d[i][j][2] = d[i-1][j][2];
d[i][j][1] = d[i-1][j][1]+1;
}
}
if(a[i] == 2){
int t = -1, t2 = -1;
if(j-1 >= 0){
d[i][j][1] = max(d[i-1][j][1],d[i-1][j-1][2]+1);
d[i][j][2] = max(d[i-1][j][2]+1,d[i-1][j-1][1]);
}
else{
d[i][j][1] = d[i-1][j][1];
d[i][j][2] = d[i-1][j][2]+1;
}
}
}
}
int ans = -1;
for(int i = 0; i <= w; ++i)
ans = max(d[t][w][1],max(ans,d[t][w][2]));
cout << ans << endl;
return 0;
}
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int d[1010][40];
int a[1010];
int main(){
int n,w;
cin >> n >> w;
memset(d,0,sizeof(d));
for(int i = 1; i <= n; ++i)
cin >> a[i];
for(int i = 1; i <= n ; ++i)
for(int j = 0; j <= w; ++j){
if(j-1>=0)
d[i][j] = max(d[i-1][j],d[i-1][j-1]);
else
d[i][j] = d[i-1][j];
if((w-j)%2 + 1 == a[i])
d[i][j]++;
}
int ans = -1;
for(int i = 0; i <= w; ++i)
ans = max(d[n][i],ans);
cout << ans << endl;
return 0;
}