Luogu1040 加分二叉树

以前觉得难

想想以前还是naive

然而我还是用的记搜

令人害怕的题也没那么难,qwq

root(i,j)表示区间[i,j]的根。

CODE:

#include<iostream>
#include<cstdio>
using namespace std;
int n, a[31];
int f[31][31], root[31][31];
int dfs(int l, int r){
	if(f[l][r]>0)return f[l][r];
	if(r<l)return 1;
	for(int i=l; i<=r; i++){
		int p=dfs(l, i-1)*dfs(i+1, r)+f[i][i];
		if(p>f[l][r]) f[l][r]=p, root[l][r]=i;
	}
	return f[l][r];
}
void print(int l, int r){
	if(r<l)return;
	if(l==r){
		printf("%d ", l);return;
	}
	printf("%d ", root[l][r]);
	print(l, root[l][r]-1);
	print(root[l][r]+1, r);
}
int main(){
	scanf("%d", &n);
	for(int i=1; i<=n; i++)
		scanf("%d", &f[i][i]);
	printf("%d\n", dfs(1, n));
	print(1, n);
	return 0;
} 

区间DP做法:

#include<iostream>
#include<cstdio>
using namespace std;
int n,v[39],f[47][47],i,j,k,root[49][49];
void print(int l,int r){
    if(l>r)return;
    if(l==r){printf("%d ",l);return;}
    printf("%d ",root[l][r]);
    print(l,root[l][r]-1);
    print(root[l][r]+1,r);
}
int main() {
    scanf("%d",&n);
    for( i=1; i<=n; i++) scanf("%d",&v[i]);
    for(i=1; i<=n; i++) {f[i][i]=v[i];f[i][i-1]=1;}
    for(i=n; i>=1; i--)
        for(j=i+1; j<=n; j++)
            for(k=i; k<=j; k++) {
                if(f[i][j]<(f[i][k-1]*f[k+1][j]+f[k][k])) {
                    f[i][j]=f[i][k-1]*f[k+1][j]+f[k][k];
                    root[i][j]=k;
                }
            }
    printf("%d\n",f[1][n]);
    print(1,n);
    return 0;
}
posted @   PushinL  阅读(116)  评论(0编辑  收藏  举报
编辑推荐:
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
阅读排行:
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 用 C# 插值字符串处理器写一个 sscanf
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!
点击右上角即可分享
微信分享提示