zoukankan      html  css  js  c++  java
  • [JLOI2015]战争调度【暴力+树形Dp】

    Online JudgeBzoj4007Luogu P3262

    Label:暴力,树形Dp

    题解

    参考了这篇blog https://www.cnblogs.com/GXZlegend/p/8300883.html。

    定义状态(dp[i][j]),表示以i为根的子树中有j个叶子节点打战的收益。

    由于是一棵标准的完全二叉树,所以转移时用类似背包的方式合并两棵子树的贡献。

    能产生贡献的只有平民(叶子节点),所以递归到叶子时才能计算贡献,而这个贡献值还与祖先的选择有关,所以必须在之前递归的时候,给那些祖先是否打战打上标记——也就是暴力枚举非叶子节点的选择。

    整个算法看似很暴力,但实际因为其特殊的树形结构,dfs函数的调用次数不会太多,详细证明可以看上面那个博客。下面是本地测试dfs调用次数的结果,可以看到当n<=10时,dfs不会调用太多次,而每次递归时合并子树的复杂度也不大,所以这个数据范围完全没问题。

    n= dfs调用次数
    1 1
    2 5
    3 21
    4 85
    5 341
    ... ...
    10 349525

    完整代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    int dp[1050][520],w[2][1050][11];
    /*
    dp[i][j]:i的子树中有j个叶子节点打战的收益 
    w[0/1][i][j]:题目给定,叶子节点i(0:作战,1:后勤)时对其第j个祖先的贡献
    mark[i]:对于叶子,i这个深度的祖先,是否选择去打战
    */
    bool mark[12];
    int n,m;
    void dfs(int x,int dep){
    	for(int i=0;i<=(1<<dep);i++)dp[x][i]=0;
    	
    	if(!dep){
    		for(int i=1;i<=n;i++){
    			if(mark[i])dp[x][1]+=w[0][x][i];
    			else dp[x][0]+=w[1][x][i];
    		}
    		return;
    	}
    	
    	mark[dep]=0,dfs(x<<1,dep-1),dfs(x<<1|1,dep-1);
    	for(int l=0;l<=1<<(dep-1);l++)for(int r=0;r<=1<<(dep-1);r++){
    		dp[x][l+r]=max(dp[x][l+r],dp[x<<1][l]+dp[x<<1|1][r]);
    	}
    
    	mark[dep]=1,dfs(x<<1,dep-1),dfs(x<<1|1,dep-1);
    	for(int l=0;l<=1<<(dep-1);l++)for(int r=0;r<=1<<(dep-1);r++){
    		dp[x][l+r]=max(dp[x][l+r],dp[x<<1][l]+dp[x<<1|1][r]);
    	}
    }
    int main(){
    	scanf("%d%d",&n,&m);n--;
    	int leaf=1<<n;
    	
    	for(int o=0;o<=1;o++)for(int i=0;i<leaf;i++)for(int j=1;j<=n;j++){
    		scanf("%d",&w[o][i+leaf][j]);
    	}
    	
    	dfs(1,n);
    	int ans=0;
    	for(int i=0;i<=m;i++)ans=max(ans,dp[1][i]);
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    php 请求另一个服务器接口返回数据
    yii2 安装
    无限分类的
    程序员学习能力提升三要素转载
    为什么有的人工作多年还是老样子
    随笔杂谈
    Ecshop商品描述上传中文名图片无法显示解决方法
    「PSR 规范」PSR-2 编码风格规范
    leetcode 之Set Matrix Zeroes(10)
    leetcode 之Plus One(9)
  • 原文地址:https://www.cnblogs.com/Tieechal/p/11523317.html
Copyright © 2011-2022 走看看