問題描述
在大家不辭辛勞的幫助下,TT 順利地完成了所有的神祕任務。
神祕人很高興,決定給 TT 一個獎勵,即白日做夢之撿貓咪遊戲。
撿貓咪遊戲是這樣的,貓咪從天上往下掉,且只會掉在 [0, 10] 範圍內,具體的座標範圍如下圖所示。
TT 初始站在位置五上,且每秒只能在移動不超過一米的範圍內接住掉落的貓咪,如果沒有接住,貓咪就會跑掉。例如,在剛開始的一秒內,TT 只能接到四、五、六這三個位置其中一個位置的貓咪。
喜愛貓咪的 TT 想要接住儘可能多的貓咪,你能幫幫他嗎?
Input
多組樣例。每組樣例輸入一個 m (0 < m < 100000),表示有 m 只貓咪。
在接下來的 m 行中,每行有兩個整數 a b (0 < b < 100000),表示在第 b 秒的時候有一隻貓咪掉落在 a 點上。
注意,同一個點上同一秒可能掉落多隻貓咪。m = 0 時輸入結束。
Output
輸出一個整數 x,表示 TT 可能接住的最多的貓咪數。
Sample input
6
5 1
4 1
6 1
7 2
7 2
8 3
0
Sample output
4
解題思路
這是一個dp題,我們按照時間來進行狀態轉移,設置數組dp[i][j][k],表示第秒,第個位置能接到貓的數量,k=1表示TT在這個位置接到貓,k=0表示TT沒有到這個位置,這個位置存在的貓。最終結果就是最後一秒,所有位置k=1的最大值。
狀態轉移方程就是
dp[i][j][1]=dp[i][j][0]+max(dp[i-1][j-1][1],max(dp[i-1][j][1],dp[i-1][j+1][1]));
然後再考慮一下邊界情況就可以了。
完整代碼
//#pragma GCC optimize(2)
//#pragma G++ optimize(2)
//#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <climits>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
const int maxn=100000+10;
int a,b,maxtime,ans,m,dp[maxn][20][2];//dp[i][j]第i秒,位置j接到的最大數量,第三維度[0]表示不在這裏,[1]表示在這裏
int getint(){
int x=0,s=1; char ch=' ';
while(ch<'0' || ch>'9'){ ch=getchar(); if(ch=='-') s=-1;}
while(ch>='0' && ch<='9'){ x=x*10+ch-'0'; ch=getchar();}
return x*s;
}
int main(){
//ios::sync_with_stdio(false);
//cin.tie(0);
while(cin>>m && m!=0){
maxtime=ans=0;
memset(dp,0,sizeof(dp));
for (int i=1; i<=m; i++){
cin>>a>>b;
dp[b][a][0]++;
maxtime=max(maxtime,b);
}
dp[0][5][1]=1;//別忘了減去
for (int i=1; i<=maxtime; i++){
for (int j=0; j<=10; j++){
if(j>0 && max(dp[i-1][j-1][1],max(dp[i-1][j][1],dp[i-1][j+1][1]))!=0)
dp[i][j][1]=dp[i][j][0]+max(dp[i-1][j-1][1],max(dp[i-1][j][1],dp[i-1][j+1][1]));
else if(max(dp[i-1][j][1],dp[i-1][j+1][1])!=0)
dp[i][j][1]=dp[i][j][0]+max(dp[i-1][j][1],dp[i-1][j+1][1]);
}
}
for (int i=1; i<=10; i++){
ans=max(ans,dp[maxtime][i][1]);
}
cout<<ans-1<<endl;
}
return 0;
}