每日一水题又来了。。。。。。(只会写水题的我日后怎么在大神们面前混呢?)
这一次带来一道动态规划的水题。。。。。。(就算是水题你也只会看题解写吧?人艰不拆啊啊)
虽然还没交(B站权限题),不过感觉还是很好想的,酷似2014noip day1T3。。。。。。。
先来看看题目吧。。。。。
【bzoj1270】[BeijingWc2008]雷涛的小猫
Description
Input
Output
Sample Input
Sample Output
8
HINT
很明显的简单递推啦,到某一个点上最大值=max(上方点的值,各个其他树上方Delta格中的最大值)+这个点有无柿子
显然从树顶往下推,一层一层的更新 。上方点的值在这个点之前已经推出来了,所以不用考虑时间,那 各个其他树上方Delta格中的最大值 如果现求的话要花费O(n)的时间,但这一层每一个点都去花O(n),那最后总的时间复杂度会升级为O(n^3),n<=2000,无法承受,注意到这一层的每一个点用的都是上Delta那一层的MAX值,用的都是同一个值,于是我们在每更新完一层的时候可以将这一层的最大值保存下来,后面就可以直接调用,时间复杂度就降到O(n^2),可以过。。。。。。和去年的《Flappy bird》(从左往右推23333)是不是很像?
c++
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int a[2005][2005]={0},n,h,delta,c[2005]={0};
int main()
{
int x1,x2;
scanf("%d%d%d",&n,&h,&delta);
for (int i=1;i<=n;i++)
{
scanf("%d",&x1);
for (int j=1;j<=x1;j++)
{
scanf("%d",&x2);
a[i][x2]++;
}
}
for (int i=h;i>=1;i--)
{
for (int j=1;j<=n;j++) a[j][i]=max(a[j][i+1],c[i+delta])+a[j][i];
for (int j=1;j<=n;j++) c[i]=max(c[i],a[j][i]);
}
printf("%d\n",c[1]);
return 0;
}