hdoj——1176免费馅饼

都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼。说来gameboy的人品实在是太好了,这馅饼别处都不掉,就掉落在他身旁的10米范围内。馅饼如果掉在了地上当然就不能吃了,所以gameboy马上卸下身上的背包去接。但由于小径两侧都不能站人,所以他只能在小径上接。由于gameboy平时老呆在房间里玩游戏,虽然在游戏中是个身手敏捷的高手,但在现实中运动神经特别迟钝,每秒种只有在移动不超过一米的范围内接住坠落的馅饼。现在给这条小径如图标上坐标:
这里写图片描述

为了使问题简化,假设在接下来的一段时间里,馅饼都掉落在0-10这11个位置。开始时gameboy站在5这个位置,因此在第一秒,他只能接到4,5,6这三个位置中其中一个位置上的馅饼。问gameboy最多可能接到多少个馅饼?(假设他的背包可以容纳无穷多个馅饼)
Input
输入数据有多组。每组数据的第一行为以正整数n,n小于100000表示有n个馅饼掉在这条小径上。在结下来的n行中,每行有两个整数x,T,x,T小于100000表示在第T秒有一个馅饼掉在x点上。同一秒钟在同一点上可能掉下多个馅饼。n=0时输入结束。

Output
每一组输入数据对应一行输出。输出一个整数m,表示gameboy最多可能接到m个馅饼。
提示:本题的输入数据量比较大,建议用scanf读入,用cin可能会超时。

Sample Input
6
5 1
4 1
6 1
7 2
7 2
8 3
0

Sample Output
4

**数塔变形:(参看上一篇:数塔)
也是找最大值
每一个饼掉下来都将其记录在数组中,然后自最后一秒往回走,沿途记录最大饼数(dp[i][i]表示第i秒,j位置接到的最大数量的饼)**

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<list>
#include<iterator>
#include<stack>
#include <queue>
#include <cstdio>
//#include<algorithm>

#pragma warning(disable:4996)
using namespace std;
typedef  long long ll;
typedef unsigned long long ull;
#define e 2.718281828459
#define INF 0x7fffffff
#define sf scanf
#define pf printf
#define sf2d(x,y) scanf("%d %d",&(x),&(y))
#define sfd(x) scanf("%d",&x)
#define sff(p) scanf("%lf",&p)
#define pfd(x) printf("%d\n",x)
#define mset(x,b) memset((x),b,sizeof(x))
const double pi = acos(-1.0);
const double eps = 1e-9;

int dp[100001][12];
int Max(int i, int j, int k) {
    int max = i > j ? i : j;
    max = max > k ? max : k;
    return max;
}

int main(void) {
    int n;
    int t, x;
    while (sfd(n), n) {
        int maxt = 0;
        mset(dp, 0);
        for(int i=1;i<=n;i++){
            sf2d(x, t);
            if (maxt < t)
                maxt = t;
            dp[t][x]++;

        }
        for (int i = maxt-1; i > 0; i--) {
            for (int j = 0; j <= 10; j++) {
                if (j == 0)
                    dp[i][j] += max(dp[i + 1][j], dp[i + 1][j + 1]);
                else
                dp[i][j] += Max(dp[i+1][j-1],dp[i + 1][j], dp[i + 1][j + 1]);
            }
        }
        int max = Max(dp[1][4],dp[1][5],dp[1][6]);


        pfd(max);

    }





    return 0;
}

也可以开一个dp数组,将数字记录在a数组,dp数组记录状态(最大饼数)
代码如下:

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<list>
#include<iterator>
#include<stack>
#include <queue>
#include <cstdio>
//#include<algorithm>

#pragma warning(disable:4996)
using namespace std;
typedef  long long ll;
typedef unsigned long long ull;
#define e 2.718281828459
#define INF 0x7fffffff
#define sf scanf
#define pf printf
#define sf2d(x,y) scanf("%d %d",&(x),&(y))
#define sfd(x) scanf("%d",&x)
#define sff(p) scanf("%lf",&p)
#define pfd(x) printf("%d\n",x)
#define mset(x,b) memset((x),b,sizeof(x))
const double pi = acos(-1.0);
const double eps = 1e-9;
int a[100001][12];
int dp[100001][12];
int Max(int i, int j, int k) {
    int max = i > j ? i : j;
    max = max > k ? max : k;
    return max;
}

int DP(int i, int j) {
    if (dp[i][j] != -1)
        return dp[i][j];
    int ans ;
    if (j == 0)
        ans = max(DP(i + 1, j), DP(i + 1, j + 1))+ a[i][j];
    else if (j == 10)
        ans = max(DP(i + 1, j - 1 ), DP(i + 1, j))+ a[i][j];
    else
    ans = Max(DP(i + 1, j - 1), DP(i + 1, j), DP(i + 1, j + 1))+ a[i][j];

    dp[i][j] =ans;//j记录
    return dp[i][j];
}


int main(void) {
    int n;
    int t, x;
    while (sfd(n), n) {
        int maxt=0;
        mset(dp, -1);
        mset(a, 0);
        for(int i=1;i<=n;i++){
            sf2d(x, t);
            if (maxt < t)
                maxt = t;
            a[t][x]++;

        }

        for (int i = 0; i < 11; i++) {
            dp[maxt][i] = a[maxt][i];
        }

        pfd(DP(0, 5));

    }





    return 0;
}


之所以DP()函数传参是(0,5)是因为下一秒可以到(1,4),(1,5),(1,6)三个位置。

猜你喜欢

转载自blog.csdn.net/jiruqianlong123/article/details/82155174