NC20663 Max Power
Max Power
https://ac.nowcoder.com/acm/problem/20663
题目大意
给一个 层的三角形,第
层有
个元素。设第
行第
列的元素为
。一开始只有第一层的元素可选择,其他层的元素
可被选择当且仅当
和
均被选择。求共选择
个元素的元素和最大值。
题解
DP。设 表示后
列用完,选了
个元素,且第
列共选择了前
行元素的最大和。那么有
其中 表示第
列前
行元素的和。
朴素转移的时间复杂度为 ,可以通过维护
,即后缀最大值进行优化,优化后的时间复杂度为
。
#include <bits/stdc++.h>
#define REP(temp, init_val, end_val) for (int temp = init_val; temp <= end_val; ++temp)
#define REPR(temp, init_val, end_val) for (int temp = init_val; temp >= end_val; --temp)
using namespace std;
int read(){
int f = 1, x = 0;
char c = getchar();
while (c < '0' || c > '9'){if(c == '-') f = -f; c = getchar();}
while (c >= '0' && c <= '9')x = x * 10 + c - '0', c = getchar();
return f * x;
}
int n, m, a[55][55], sum[55][55] = {0}, sum2[55][55];
int f[55][1305][55], tri[55];
int g[55][1305][55];
/* inline int q(int x, int y, int bc){
int rbc =
return sum2[y][y + bc]
}*/
void init(){
REP(i, 1, n)
REP(j, 1, n - i + 1)
a[i][j] = read();
REP(i, 1, n){
REP(j, 1, n - i + 1)
sum[j][i] = sum[j - 1][i] + a[j][i];
}
REPR(i, n, 1){
sum2[i][i] = a[1][i];
REPR(j, i - 1, 1)
sum2[j][i] = sum2[j + 1][i] + sum[i - j + 1][j];
}
/* REP(i, 1, n)
REP(j, 1, n - i + 1)
sum[j][i] += sum[j][i - 1];
tri[0] = 0;
REP(i, 1, n)
tri[i] = tri[i - 1] + i; */
}
void solve(){
memset(f, 0xC0, sizeof(f));
memset(g, 0xC0, sizeof(g));
f[n + 1][0][0] = g[n + 1][0][0] = 0;
REPR(i, n, 1){
REPR(j, n - i + 1, 1){
int dd = sum[j][i];
REP(t, j, m){
f[i][t][j] = g[i + 1][t - j][j - 1] + dd,
g[i][t][j] = max(f[i][t][j], g[i][t][j + 1]);
}
}
REP(t, 0, m){
f[i][t][0] = g[i + 1][t][0],
g[i][t][0] = max(f[i][t][0], g[i][t][1]);
}
}
int ans = 0;
REP(i, 0, n)
ans = max(ans, f[1][m][i]);
printf("%d\n", ans);
}
int main(){
while (scanf("%d%d", &n, &m) == 2){
init();
solve();
}
return 0;
} 
查看1道真题和解析