老师让我们补做了一下PKUSC那周的题目= =

  这次好像是树形DP的专题?感觉题目还是很棒的,值得将来再回头学习。

Cateran

  树形状压DP,其实在看题解之前我似乎并没有搞懂这题在干什么……

  对于节点 i ,我们考虑f[i][j]表示 i 这棵子树中,分部包含情况为 j 的最大收益,因为一个分部管的是从x到根的所有点,所以对于一个点来说,管它的就是子树中的所有分部,所以就可以dp啦~依次枚举每个儿子的子树中有哪些分部,用一个辅助数组,我们可以搞:

  c[j]=f[x][j];

  c[j]=max(c[j],f[y][k]+f[x][j^k]);

  f[x][j]=c[j];

依次搞下来即可。

  初始化就是分部全部在 x 节点。计算完后要加上符合的收益(T种中的某一些……)

 1 //20150527 cateran
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<iostream>
 6 #include<algorithm>
 7 #define rep(i,n) for(int i=0;i<n;++i)
 8 #define F(i,j,n) for(int i=j;i<=n;++i)
 9 #define D(i,j,n) for(int i=j;i>=n;--i)
10 #define pb push_back
11 using namespace std;
12 typedef long long LL;
13 inline int getint(){
14     int r=1,v=0; char ch=getchar();
15     for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1;
16     for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch;
17     return r*v;
18 }
19 const int N=4100;
20 /*******************template********************/
21 
22 int head[110],nxt[220],to[220],cnt;
23 void add(int x,int y){
24     to[++cnt]=y; nxt[cnt]=head[x]; head[x]=cnt;
25     to[++cnt]=x; nxt[cnt]=head[y]; head[y]=cnt;
26 }
27 int n,m,T,a[110][15],b[N],c[N];
28 int f[110][N];
29 
30 void dfs(int x,int fa){
31     rep(j,(1<<m)){
32         f[x][j]=0;
33         rep(i,m) if (j&(1<<i)) f[x][j]-=a[x][i+1];
34 //        printf("f[%d][%d]=%d\n",x,j,f[x][j]);
35     }
36     int y;
37     for(int i=head[x];i;i=nxt[i])
38         if ((y=to[i])!=fa){
39             dfs(y,x);
40             rep(j,(1<<m)) c[j]=f[x][j];
41             rep(j,(1<<m))
42                 for(int k=j;k;k=(k-1)&j)
43                     c[j]=max(c[j],f[y][k]+f[x][j^k]);
44             rep(j,1<<m) f[x][j]=c[j];
45         }
46     rep(i,1<<m)
47         for(int k=i;k;k=(k-1)&i) f[x][i]+=b[k];
48 //    rep(i,1<<m) printf("f[%d][%d]=%d\n",x,i,f[x][i]);
49 }
50 int main(){
51 #ifndef ONLINE_JUDGE
52     freopen("cateran.in","r",stdin);
53     freopen("cateran.out","w",stdout);
54 #endif
55     n=getint(); m=getint();
56     F(i,2,n){
57         int x=getint(),y=getint();
58         add(x,y);
59     }
60     F(i,1,n) F(j,1,m) a[i][j]=getint();
61     T=getint();
62     F(i,1,T){
63         int v=getint(),c=getint(),now=0,x;
64         F(j,1,c){
65             x=getint();
66             now|=1<<(x-1);
67         }
68         b[now]+=v;
69     }
70     dfs(1,0);
71     printf("%d\n",f[1][(1<<m)-1]);
72     return 0;
73 }
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-11-11
  • 2021-12-28
  • 2021-12-15
  • 2021-12-15
  • 2021-11-19
猜你喜欢
  • 2022-12-23
  • 2021-11-24
  • 2022-12-23
  • 2021-12-15
  • 2021-12-14
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案