1 条题解

  • 0
    @ 2025-8-24 21:47:06

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Shikita
    **

    搬运于2025-08-24 21:47:06,当前版本为作者最后更新于2018-09-13 17:36:36,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    的确是一道树形DP的好题目

    题意简述:对于一颗完全二叉树,可以将叶子节点设置为两种状态(简称为0和1),如果该叶子节点与其某个祖先的状态相同,那么就有一个贡献值,两者都为0或1时对应两种不同的贡献值,求设置某种状态小于m时的最大贡献

    由于这是一颗完全二叉树,那么其实就是分别求左右两个树形背包然后合并的结果

    设 f[i][j] 表示以i为根的子树中,j个叶子节点选择战争的最大总贡献值。

    #include<bits/stdc++.h>
    using namespace std;
    inline int read()
    {
        int x=0;
        char c=getchar();
        bool flag=0;
        while(c<'0'||c>'9') {if(c=='-')flag=1;c=getchar();}
        while(c>='0'&&c<='9'){x=(x+(x<<2)<<1)+ c-'0';c=getchar();}
        return flag?-x:x;
    }
    int n,m;
    int gh[1030][15],pt[1030][15],f[1030][1030],vis[15];
    void dfs(int x,int y) //x表示节点,y表示层数
    {
    	for(int i=0;i<=1<<y;i++) f[x][i]=0;//全部初始化
    	if(!y) //如果已经完成搜索(dp)
        {
        for(int i=1;i<=n;i++) 
          if(vis[i]) f[x][1]+=gh[x][i]; 
          else f[x][0]+=pt[x][i];return;
          //把贡献分别上交,退出
        }
    	vis[y]=0,dfs(x<<1,y-1),dfs(x<<1|1,y-1);//分别去子节点
    	for(int i=0;i<=1<<(y-1);i++) 
          for(int j=0;j<=1<<(y-1);j++) 
            f[x][i+j]=max(f[x][i+j],f[x<<1][i]+f[x<<1|1][j]);
    	vis[y]=1,dfs(x<<1,y-1),dfs(x<<1|1,y-1);
    	for(int i=0;i<=1<<(y-1);i++) 
          for(int j=0;j<=1<<(y-1);j++)
            f[x][i+j]=max(f[x][i+j],f[x<<1][i]+f[x<<1|1][j]);
        //在分别完成子树的搜索之后进行子树的合并
    }
    int main()
    {
    	int ans=0;
    	n=read(),m=read(),n--;//不能超过n所以这里直接进行--处理
    	for(int i=0;i<(1<<n);++i) 
          for(int j=1;j<=n;++j) 
            gh[i+(1<<n)][j]=read();//这个是存打仗的贡献,(givehead)
    	for(int i=0;i<(1<<n);++i) 
          for(int j=1;j<=n;++j) 
            pt[i+(1<<n)][j]=read();//这个是存种地的贡献,(刨土)
    	dfs(1,n);
    	for(int i=0;i<=m;++i) ans=max(ans,f[1][i]); cout<<ans<<endl;
        //根据dp方程的推导,以1为根选取1~m个节点的最大值
    }
    

    望大佬们多多海涵,感谢斧正

    • 1

    信息

    ID
    2335
    时间
    1000ms
    内存
    125MiB
    难度
    6
    标签
    递交数
    0
    已通过
    0
    上传者