首页 > 代码库 > [BZOJ 1270][BeijingWc2008]雷涛的小猫

[BZOJ 1270][BeijingWc2008]雷涛的小猫

题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1270

看到题面上的PKU宿舍,又让我怀念起七月份在PKU上课的那段快乐时光。。。

这也许是WC的送分题吧,比较简单的动规,但是也很巧妙。用f1[i]表示小猫在高度i时得到的柿子个数最大值,f2[i]表示在当前高度上,小猫在第i根柱子上得到的柿子个数最大值。

然后高度从高到低遍历,维护f1、f2即可。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>

#define MAXN 5050

using namespace std;

int map[MAXN][MAXN];
int f1[MAXN],f2[MAXN]; //f1[i]=高度为i,猫得到的柿子个数最大值,f2[i]=当前高度猫在第i个柱子上得到的柿子个数最大值

int main()
{
    int n,h,d,ni,t;
    scanf("%d%d%d",&n,&h,&d);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&ni);
        for(int j=1;j<=ni;j++)
        {
            scanf("%d",&t);
            map[i][t]++;
        }
    }
    for(int i=h;i>=1;i--)
    {
        t=i+d;
        if(t<=h) t=f1[i+d]; //如果猫之前跳跃过,那么猫在之前的高度上得到的柿子个数最大值为t
        else t=0;
        for(int j=1;j<=n;j++)
        {
            f2[j]=max(f2[j],t)+map[j][i];
            f1[i]=max(f1[i],f2[j]);
        }
    }
    printf("%d\n",f1[1]);
    return 0;
}



[BZOJ 1270][BeijingWc2008]雷涛的小猫