luoguP1040 区间DP(记忆化 加分二叉树
2024-09-28 06:18:09
dp[l][r]记录中序序列为l, l+1..r的最大加分值
root[l][r]记录这个序列的根节点
转移
i 为根节点
dp[l][r] = max(dp[l][i-1]*dp[l+1][r]+a[i], dp[l][r])
顺势更新root[l][r]
#include <bits/stdc++.h>
#define pb push_back
#define po pop_back
#define fi first
#define se second using namespace std; typedef long long ll;
typedef pair<int, int> P; const int MAXN = ;
const int MAXE = 1e5+;
const int MAXV = 1e5+;
const int INF = 0x3f3f3f3f; int a[MAXN]; int dp[MAXN][MAXN];
int root[MAXN][MAXN];
int n; int dfs(int l, int r)
{
if (l > r) return ; //leave
if (dp[l][r] > ) return dp[l][r];
if (l == r)
{
root[l][r] = l;
dp[l][r] = a[l];
return dp[l][r];
}
for (int i = l; i <= r; i++)
{
int res = dfs(l, i-)*dfs(i+, r)+a[i];
if (res > dp[l][r])
{
dp[l][r] = res;
root[l][r] = i;
}
}
return dp[l][r];
}
void print(int l, int r)
{
if (l > r) return ;
if (l == r)
{
printf("%d ", root[l][l]);
return ;
}
printf("%d ", root[l][r]);
print(l, root[l][r]-);
print(root[l][r]+, r);
}
int main()
{
//freopen("in.txt", "r", stdin);
while (cin >> n)
{
for (int i = ; i <= n; i++) cin >> a[i];
memset(dp, , sizeof(dp));
cout << dfs(, n) << endl;
print(, n);
cout << endl;
}
return ; }
最新文章
- Python-0 简述
- Android menu 简单创建
- ionic 原生日历控件不支持,改用 datepicker-for-ionic
- Hibernate Cascade &; Inverse
- div section article aside的理解
- ExtractFileDir 与 ExtractFilePath 的差别
- [异常解决] Make nRF51 DFU Project Appear ";fatal error: uECC.h: No such file or directory";
- 最受欢迎linux命令
- sdut 6-2 多态性与虚函数
- Java基础——第一个记事本代码与Java注释
- Redis单机版和集群版的安装和部署
- DNS Server Centos 7
- HDOJ-2039
- 测试那些事儿—软测必备的Linux知识(四)
- [PHP]Nginx与PHP的文件上传大小限制
- 测试json字符和java对象属性不一样在多个json框架下转换的表现
- (笔记)AES加密在线计算工具
- layui图片显示
- echatrs可视化图在隐藏后显示不出来或是宽度出现问题
- day27 python学习 logging