思路:
- 简单动态规划。
- 两个维度:时间地点,这十分好想,但是先前几秒的位置限制(有些点走不到)十分让人迷惑。那么本题的关键就在倒序计算,如此许多问题迎刃而解。
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + 5;
int N;
int maxtime;
int dp[15][maxn];
void INIT(){
maxtime = 0;
memset(dp , 0 , sizeof(dp));
return ;
}
int main(){
while(cin>>N && N){
INIT();
for(int i=1;i<=N;i++){
int x,t;
scanf("%d%d" , &x , &t);
dp[x][t]++;
maxtime = max(maxtime , t);
}
for(int t = maxtime ; t>=0 ; t--){
for(int i = 0 ; i <= 10 ; i++){
if(i<10 && i)
dp[i][t] += max(dp[i][t+1] , max(dp[i-1][t+1] , dp[i+1][t+1]));
else if(i)
dp[i][t] += max(dp[i][t+1] , dp[i-1][t+1]);
else
dp[i][t] += max(dp[i][t+1] , dp[i+1][t+1]);
}
}
cout<<dp[5][0]<<endl;
}
return 0;
}
二刷:
#include <iostream>
#include <cstring>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1e5 + 5;
int N;
int w[maxn][15];
int dp[2][15];
int maxtime;
int main(){
while(cin>>N && N){
maxtime = 0;
memset(w , 0 , sizeof(w));
memset(dp , 0 , sizeof(dp));
while(N--){
int x,t;
scanf("%d%d" , &x , &t);
w[t][x+1]++;
maxtime = max(maxtime , t);
}
int t=0;
for(int i=maxtime;i;i--){
t=1-t;
for(int j=1;j<=11;j++)
dp[t][j] = max(max(dp[1-t][j-1] , dp[1-t][j]) , dp[1-t][j+1]) + w[i][j];
}
cout<<max(dp[maxtime%2][5] , max(dp[maxtime%2][6] , dp[maxtime%2][7]))<<endl;
}
return 0;
}