题目链接:1006-免费馅饼_2021秋季算法入门班第七章习题:动态规划1 (nowcoder.com)
一开始以为是背包,想了想好像不是,和数字三角形有点像。
我们每加入一种花,对于当前dp[i][j]来说,其最大价值应为max(dp[i-1][1~j-1]+a[i][j],dp[i][j])
其次路径输出要最小字典序,要从低到高遍历回去求得路径。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll int a[105][105], dp[105][105];
vector<int>path;
int main() {
int f, v;
cin >> f >> v;
for (int i = 1; i <= f; i++) {
for (int j = 1; j <= v; j++) {
cin >> a[i][j];
dp[i][j] = -9e18; //因为有负数的出现所以dp要初始化成最小值
}
}
for (int i = 1; i <= v; i++) {
dp[1][i] = a[1][i];
}
for (int i = 2; i <= f; i++) {
for (int j = i; j <= v; j++) {
for (int k = 1; k < j; k++) {
dp[i][j] = max(dp[i][j], dp[i - 1][k] + a[i][j]);
}
}
}
ll ans = -9e18;
int pos = -1;
for (int i = 1; i <= v; i++) {
if (dp[f][i] > ans) {
ans = max((ll)dp[f][i], ans);
pos = i;
}
}
cout << ans << endl;
ans -= a[f][pos];
path.push_back(pos);
for (int i = f - 1; i > 0; i--) {
for (int j = 1; j <= v; j++) {
if (dp[i][j] == ans) {
path.push_back(j);
ans -= a[i][j];
break;
}
}
}
for (int i = path.size() - 1; i >= 0; i--) {
cout << path[i] << " ";
}
return 0;
}