題面:
撿貓咪遊戲規則如下:
貓咪從天上往下掉,且只會掉在 [0, 10] 範圍內,具體的座標範圍如下圖所示
TT 初始站在位置五上,且每秒只能在移動不超過一米的範圍內接住掉落的貓咪,如果沒有接住,貓咪就會跑掉。例如,在剛開始的一秒內,TT 只能接到四、五、六這三個位置其中一個位置的貓咪。
請求出最多可能接到的貓咪數
多組樣例輸入。每組樣例輸入一個 m (0 < m < 100000),表示有 m 只貓咪。
在接下來的 m 行中,每行有兩個整數 a b (0 < b < 100000),表示在第 b 秒的時候有一隻貓咪掉落在 a 點上。
注意,同一個點上同一秒可能掉落多隻貓咪。m = 0 時輸入結束
輸出一個整數 x,表示 TT 可能接住的最多的貓咪數
sample input:
6
5 1
4 1
6 1
7 2
7 2
8 3
0
sample output:
4
思路:
- 對於第一秒,4,5,6位置沒有區別,可以直接將值付到dp數組中。
- 對於之後的轉移過程需要分情況,對於邊界的兩個點(0,10位置),只存在單邊界的轉移,而對於中間位置可以從三個狀態進行轉移
- 根據分析可以列出狀態轉移方程,對於題目給出的最大時間 li ,
- 出現MLE不要怕,
微笑着面對他,看一下自己數組是不是開大了,尤其是像我們要使用memset對數組進行初始化的情況;如果還不行,就看一下是否存儲了不必要的大數,比如代碼中的const int N.本來我定義數組用了N,換成直接定義後就成功AC了。
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
using namespace std;
//const int N=1e6+1;
int a[100001][11],dp[100001][11];
int thmax(int a,int b,int c)
{
int temp=max(a,b);
temp=max(temp,c);
return temp;
}
int main()
{
int m;
while(scanf("%d",&m)!=EOF)
{
if(m==0) return 0;
int pos,tim;
memset(a,0,sizeof(a));
memset(dp,0,sizeof(dp));
int li=0;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&pos,&tim);
a[tim][pos]++;
li=max(li,tim);
}
dp[1][4]=a[1][4];
dp[1][5]=a[1][5];
dp[1][6]=a[1][6];
for(int i=2;i<=li;i++)
{
for(int j=0;j<=10;j++)
{
if(j==0)//單獨邊界處理
dp[i][j]=max(dp[i-1][j],dp[i-1][j+1])+a[i][j];
else if(j==10)
dp[i][j]=max(dp[i-1][j],dp[i-1][j-1])+a[i][j];
else
dp[i][j]=thmax(dp[i-1][j+1],dp[i-1][j],dp[i-1][j-1])+a[i][j];
}
}
int ans=0;
for(int i=0;i<=10;i++)
ans=max(ans,dp[li][i]);
printf("%d\n",ans);
}
return 0;
}