C
捡猫咪游戏是这样的,猫咪从天上往下掉,且只会掉在 [0, 10] 范围内,具体的坐标范围如下图所示。
初始站在位置五上,且每秒只能在移动不超过一米的范围内接住掉落的猫咪,如果没有接住,猫咪就会跑掉。例如,在刚开始的一秒内,只能接到四、五、六这三个位置其中一个位置的猫咪。
如何想要接住尽可能多的猫咪?
思路
- 设 d p [ i ] [ j ] dp[i][j] dp[i][j]表示第 i i i秒站在 j j j位置上的最大值。
- 状态转移方程: d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ j − 1 ] , d p [ i − 1 ] [ j ] , d p [ i − 1 ] [ j + 1 ] ) dp[i][j]=max(dp[i-1][j-1],dp[i-1][j],dp[i-1][j+1]) dp[i][j]=max(dp[i−1][j−1],dp[i−1][j],dp[i−1][j+1])
- 利用滚动数组优化空间
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int m,a,b,maxt;
int cat[100010][11];
int dp[2][12];
int main(){
while(true){
scanf("%d",&m);
if(m==0) break;
memset(cat,0,sizeof cat);
memset(dp,0,sizeof dp);
maxt=0;
while(m--){
scanf("%d%d",&a,&b);
maxt=max(maxt,b);
cat[b][a]++;
}
for(int i=4;i<=6;i++){
dp[1][i]=cat[1][i];
}
int t=0;
for(int i=2;i<=maxt;i++){
for(int j=0;j<=10;j++){
if(j==0){
dp[t][j]=max(dp[1-t][j],dp[1-t][j+1])+cat[i][j];
}
else if(j==10){
dp[t][j]=max(dp[1-t][j-1],dp[1-t][j])+cat[i][j];
}
else{
dp[t][j]=max(dp[1-t][j-1],max(dp[1-t][j],dp[1-t][j+1]))+cat[i][j];
}
}
t=1-t;
}
int ans=0;
for(int i=0;i<=10;i++){
ans=max(ans,dp[1-t][i]);
}
printf("%d\n",ans);
}
}