zoukankan      html  css  js  c++  java
  • 洛谷P2014 选课

    传送门啦

    一个树上dp(树上背包问题),我用了两个方法,都A掉了,这个题数据可能太水了,第一次打错了都A了,不过错误已经改掉了。

    第一次就是用的树上背包,差不多是裸题了吧。

    $ f[i][j] $ 表示以 $ i $ 为根的子树中选 $ j $ 个的最优方案,因为我们建立了一个虚点,所以最后用了 $ f[0][m+1]
    $

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn = 305;
    
    inline int read(){
    	char ch = getchar();
    	int f = 1 ,x = 0;
    	while(ch > '9' || ch < '0'){if(ch == '-')f = -1;ch = getchar();}
    	while(ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + ch - '0';ch = getchar();}
    	return x * f;
    }
    
    int n,m,u,w[maxn];
    int head[maxn],tot;
    int f[maxn][maxn],size[maxn];
    
    struct Edge{
    	int from,to,next,val;
    }edge[maxn << 1];
    
    void add(int u,int v){
    	edge[++tot].from = u;
    	edge[tot].to = v;
    	edge[tot].next = head[u];
    	head[u] = tot;
    }
    
    void dfs(int x,int fa){
        size[x] = 1;
    	f[x][1] = w[x];
        for(int i=head[x];i;i=edge[i].next){
            int v = edge[i].to;
            if(v != fa){
                dfs(v , x);
                size[x] += size[v];
                for(int j=size[x];j>=2;j--)
                    for(int k=0;k<=size[v];k++)
                        if(j > k)
                            f[x][j] = max(f[x][j] , f[x][j-k] + f[v][k]);
            }
        }
    }			
    
    int main(){
    	n = read(); m = read();
    	for(int i=1;i<=n;i++){
    		u = read(); w[i] = read();
    		add(u , i); add(i , u);
    	}
    	dfs(0 , -1);
    	printf("%d
    ",f[0][m+1]);
    	return 0;
    }	
    

    这个 $ dfs $ 是以 $ x $ 为根,还剩下 $ t $ 个课程可以选,这个 $ f $ 数组没有包含根节点,所以最后没有用 $ m + 1 $ .

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn = 305;
    
    inline int read(){
        char ch = getchar();
        int f = 1 ,x = 0;
        while(ch > '9' || ch < '0'){if(ch == '-')f = -1;ch = getchar();}
        while(ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + ch - '0';ch = getchar();}
        return x * f;
    }
    
    int n,m,u,w[maxn];
    int head[maxn],tot;
    int f[maxn][maxn];
    
    struct Edge{
        int from,to,next;
    }edge[maxn << 1];
    
    void add(int u,int v){
        edge[++tot].from = u;
        edge[tot].to = v;
        edge[tot].next = head[u];
        head[u] = tot;
    }
    
    void dfs(int x,int t){
        if(t == 0)  return ;
        for(int i=head[x];i;i=edge[i].next){
            int v = edge[i].to;
            for(int k=0;k<=t;k++)
                f[v][k] = f[x][k] + w[v];
            dfs(v , t - 1);
            for(int k=1;k<=t;k++)
                f[x][k] = max(f[x][k] , f[v][k-1]); 
        }
    }
    
    int main(){
        n = read(); m = read();
        for(int i=1;i<=n;i++){
            u = read(); w[i] = read();
            add(u , i);
        }
        dfs(0 , m);
        printf("%d
    ",f[0][m]);
        return 0;
    }
    顺风不浪,逆风不怂。
  • 相关阅读:
    BZOJ2253: [2010 Beijing wc]纸箱堆叠
    解题:CF1055F Tree and XOR
    解题:JSOI 2011 柠檬
    解题:NOI 2009 诗人小G
    2019.2.28&2019.3.1 考试
    省选前作业题汇总2
    解题:LNOI 2014 LCA
    省选前作业题汇总1
    2019.2.26 考试
    解题:SDOI 2014 重建
  • 原文地址:https://www.cnblogs.com/Stephen-F/p/9879180.html
Copyright © 2011-2022 走看看