TT的獎勵(動態規劃)

問題描述

在大家不辭辛勞的幫助下,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],表示第ii秒,第jj個位置能接到貓的數量,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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章