bzoj1270

来源:互联网 发布:网络培训课件 编辑:程序博客网 时间:2024/06/12 22:58

多刷水题,有助身心健康

题面我就不粘了……

一个dp的裸题
f[i][j] 表示高度为 i,在第j棵树时最大的收益
这样f[i][j] 就可以从f[i][j-1] 和 f[i-delta][?] 转移过来
所以再开一个数组dp,用dp[i] 表示在i层的最大收益,这样就可以O(1)转移
复杂度为O(N * H)
注:题目中一个位置可能不止有一颗柿子

(很丑只能用来对拍的代码,您也许一般就AC了)

#include<bits/stdc++.h>using namespace std;#define FOR(i,s,t) for(int i=(s);i<=(t);i++)inline int read(void) {    int x = 0, c, f = 1;    do {c=getchar(); if(c=='-') f = -1;} while(c<'0'||c>'9');    do {x = x*10+c-'0';c=getchar();}while(c>='0'&&c<='9');    return x * f;}const int N = 2100, INF = 0x3f3f3f3f;int T[N][N];int n, h, d;int f[N][N],dp[N];void DP(void) {    int ans = 0;    for (int i = 1; i <= n; i++) f[h][i] = T[h][i];    for (int i = h-1; i >= 0; i--)        for (int j = 1; j <= n; j++) {            f[i][j] = max(f[i+1][j], i + d > h ? -INF : dp[i+d]) + T[i][j];            dp[i] = max(dp[i], f[i][j]);        }    printf("%d\n",dp[0]);   }int main(){    n = read(), h = read(), d = read();    for (int i = 1; i <= n; i++) {        int m = read(), x;        while (m--) {            x = read(), T[x][i]++;        }    }    DP();}
1 0
原创粉丝点击