NC229312. 防御法阵
描述
输入描述
第一行三个整数 ,含义见题目描述。
接下来 行,每行首先有正整数 表示该块城墙下方的法阵数量,接下来 个正整数,依次是第 个法阵破坏后的经验值 ,第 法阵破坏的用时 。
第 个法阵破坏后的经验值和破坏用时,直到第 个法阵。
输出描述
一个正整数,表示牛牛能够得到的最大经验值。
示例1
输入:
5 3 5 2 1 5 9 2 3 1 10 1 2 2 3 1 9 4 3 1 10 5 2 1 4 4 8 8 9 9 7 7 6 1
输出:
52
说明:
城墙共5段,每段在5秒内破坏,不计相邻城墙的破坏效果加成的情况下,依次能收到最多9,3,9,5,6点经验值。破坏3段,此时选择先破坏中间的城墙获得9点经验值,再依次获得5,6点经验值,最终能够造成最大52点经验值。计算过程如下示例2
输入:
5 5 5 2 1 5 9 2 3 1 10 1 2 2 3 1 9 4 3 1 10 5 2 1 4 4 8 8 9 9 7 7 6 1
输出:
223
C++ 解法, 执行用时: 62ms, 内存消耗: 3232K, 提交时间: 2021-10-17 20:54:46
#include <bits/stdc++.h> #define N 10005 #define LL long long using namespace std; int n, m, i, j, k, c, t, v, d[205], a[N]; LL ans, f[N][35]; int main(){ scanf("%d%d%d", &n, &m, &c); for(i=1; i<=n; i++){ memset(d, 0, sizeof(d)); scanf("%d", &k); while(k--){ scanf("%d%d", &v, &t); for(j=c; j>=t; j--){ d[j] = max(d[j], d[j-t]+v); } } f[i][1] = a[i] = d[c]; } for(c=2; c<=m; c++){ for(i=1; i+c-1<=n; i++){ f[i][c] = max(f[i][c-1]*2+a[i+c-1], f[i+1][c-1]*2+a[i]); } } for(i=1; i+m-1<=n; i++) ans = max(ans, f[i][m]); printf("%lld\n", ans); return 0; }