動態規劃:撿貓遊戲

題面:

撿貓咪遊戲規則如下:
貓咪從天上往下掉,且只會掉在 [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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章