• 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
    ", 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
    ",f[1][n]);
        print(1,n);
        return 0;
    }
    
  • 相关阅读:
    TCP/IP协议总结(马士兵教育)
    socket和TCP/IP三次握手的对应关系
    VMWare中添加多个linux节点
    试题分析
    c#数据筛选和排序
    实现Windows程序的数据绑定
    实现Windows程序的数据更新
    使用ListView控件展示数据
    构建布局良好的Windows程序
    初识Windows程序
  • 原文地址:https://www.cnblogs.com/pushinl/p/9892340.html
Copyright © 2020-2023  润新知