• luoguP1040 加分二叉树


    在做各类DP的时候都要思路清晰!

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N = 30+9;
    inline int read() {
    	char ch = getchar(); int f = 1, x = 0;
    	while(ch<'0' || ch>'9') {if(ch=='-') f = -1; ch = getchar();}
    	while(ch>='0' && ch<='9') {x = (x<<1)+(x<<3)+(ch^48); ch = getchar();}
    	return x*f;
    } 
    
    int n;
    long long f[N][N];//f[i][j]: 序列以[i, j]范围内的点做子树时的最大分数
    int root[N][N];//f[i][j]为最大分数时的子树[i, j]的根 
    
    void pre() {
    	n = read();
    	for(int i = 1; i <= n; i++) f[i][i] = read(), f[i][i-1] = 1, root[i][i] = i;//下面的需要
            //因为这题是乘积,所以才初始化为1
    	//同时给叶子节点初始化根 
    }
    
    void print_way(int l, int r) {
    	if(l > r) return ;
    	printf("%d ", root[l][r]);
    	print_way(l, root[l][r]-1);
    	print_way(root[l][r]+1, r);
    }
    
    void solve() {
    	int j;
    	for(int l = 2; l <= n; l++) {
    		for(int i = 1; i+l-1 <= n; i++) {
    			j = i+l-1;
    			for(int 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("%lld
    ", f[1][n]);
    	print_way(1, n);
    }
    
    int main() {
    	pre();
    	solve();
    	return 0;
    } 
    
  • 相关阅读:
    MVC3 的路由Test
    表连接
    Moq MVC 初窥门径(一)
    FATAL ERROR: JS Allocation failed process out of memory
    版本号的意义
    JavaScript 类型的隐式转换
    翻译foreach语句
    一次http请求的全过程(附mmap文件下载)
    AOP学习笔记
    Kindle3之中文乱码问题
  • 原文地址:https://www.cnblogs.com/tyner/p/11746996.html
Copyright © 2020-2023  润新知