zoukankan      html  css  js  c++  java
  • bzoj5314:[Jsoi2018]潜入行动

    传送门

    这真的是个很简单的树形背包,因为我都会写

    首先设(f[i][j][0/1][0/1])表示(i)节点的子树内放了(j)个监听器,(i)点上是否放了监听器,(i)是否被监听

    接下来推方程(情况有点多,但是确实好想):

    (son)(i)节点的子节点集合

    1、(i)节点没有被监听也没有放监听器

    [f[i][j+t][0][0]=sum_{yin son}f[i][j][0][0]*f[y][t][0][1] ]

    2、(i)节点被监听但是没有放监听器

    [f[i][j+t][0][1]=sum_{yin son}f[i][j][0][0]*f[y][t][1][1]+f[i][j][0][1]*(f[y][t][1][1]+f[y][t][0][1]) ]

    3、(i)节点没有被监听,但是放了监听器

    [f[i][j+t][1][0]=sum_{yin son}f[i][j][1][0]*(f[y][t][0][0]+f[y][t][0][1]) ]

    4、(i)节点被监听,也放了监听器

    [f[i][j+t][1][1]=sum_{yin son}f[i][j][1][0]*(f[y][t][1][0]+f[y][t][1][1])+f[i][j][1][1]*(f[y][t][1][0]+f[y][t[1][1]+f[y][t][0][0]+f[y][t][0][1]) ]

    然后就可以(dp)

    bzoj是真的慢,用mod又被卡了,还是改成快速乘和龟速加才A掉

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    #define rg register
    const int maxn=1e5+10,mod=1e9+7;
    int size[maxn],n,k,cnt,pre[maxn*2],nxt[maxn*2],h[maxn],f[maxn][110][2][2],g[110][2][2];
    void read(int &x)
    {
    	char ch;bool ok;
    	for(ok=0,ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')ok=1;
    	for(x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());if(ok)x=-x;
    }
    void add(int x,int y)
    {
    	pre[++cnt]=y,nxt[cnt]=h[x],h[x]=cnt;
    	pre[++cnt]=x,nxt[cnt]=h[y],h[y]=cnt;
    }
    int mul(int x,int y){return 1ll*x*y-1ll*x*y/mod*mod;}
    int inc(int x,int y){return x+y>mod?x+y-mod:x+y;}
    void dfs(int x,int fa)
    {
    	size[x]=1;f[x][0][0][0]=f[x][1][1][0]=1;
    	for(rg int i=h[x];i;i=nxt[i])
    		if(pre[i]!=fa){
    			dfs(pre[i],x);
    			for(rg int j=0;j<=min(k,size[x]);j++)
    				for(rg int t=0;t<=min(k,size[pre[i]]);t++){
    					if(j+t>k)break;
    					g[j+t][0][0]=inc(g[j+t][0][0],mul(f[x][j][0][0],f[pre[i]][t][0][1]));
    					g[j+t][0][1]=inc(inc(g[j+t][0][1],mul(f[x][j][0][0],f[pre[i]][t][1][1])),mul(f[x][j][0][1],(f[pre[i]][t][1][1]+f[pre[i]][t][0][1])));
    					g[j+t][1][0]=inc(g[j+t][1][0],mul(f[x][j][1][0],(f[pre[i]][t][0][0]+f[pre[i]][t][0][1])));
    					g[j+t][1][1]=inc(inc(g[j+t][1][1],mul(f[x][j][1][0],f[pre[i]][t][1][0]+f[pre[i]][t][1][1])),mul(f[x][j][1][1],inc(f[pre[i]][t][1][0],inc(f[pre[i]][t][1][1],inc(f[pre[i]][t][0][0],f[pre[i]][t][0][1])))));
    				}
    			size[x]+=size[pre[i]];
    			for(rg int j=0;j<=min(k,size[x]);j++){
    				f[x][j][0][0]=g[j][0][0];g[j][0][0]=0;
    				f[x][j][0][1]=g[j][0][1];g[j][0][1]=0;
    				f[x][j][1][0]=g[j][1][0];g[j][1][0]=0;
    				f[x][j][1][1]=g[j][1][1];g[j][1][1]=0;
    			}
    		}
    }
    int main()
    {
    	read(n),read(k);
    	for(rg int i=1,x,y;i<n;i++)read(x),read(y),add(x,y);
    	dfs(1,0);
    	printf("%d
    ",inc(f[1][k][0][1],f[1][k][1][1]));
    }
    
    
  • 相关阅读:
    JavaScript小笔记の经典算法等....
    SEO
    幻灯片の纯CSS,NO JavaScript
    试说明采用双缓冲技术如何进行I/O操作
    常用的缓冲技术有哪几种?
    什么是缓冲,引入缓冲的原因是什么?
    什么是设备控制块,它主要包括什么内容,简述其作用?
    进程的逻辑设备如何与一个物理设备建立对应的关系?
    什么是设备独立性,引入这一概念有什么好处?
    试叙述段页式地址变换过程。
  • 原文地址:https://www.cnblogs.com/lcxer/p/10649749.html
Copyright © 2011-2022 走看看