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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章