zoukankan      html  css  js  c++  java
  • Strategic game策略游戏

    POJ

    题意:有一座城市,有很多道路将整个城市连起来,整体上看上去像一棵树.需要放置尽可能少的士兵,保卫树上所有的边.士兵只能放在节点上,但是却可以保卫所有与这个节点相邻的边.求最少需要放置的士兵数量?

    分析:树的最大独立集问题,树形DP来做.设(f[x][1/0])表示以x节点为根的子树中,x节点放/不放士兵的 最少需要放置士兵的数量.

    设y是x的子节点,则,

    (f[x][0]+=f[y][1]),x节点不放士兵,则x的所有子节点y都要放置士兵.

    (f[x][1]+=min(f[y][0],f[y][1])),x节点放了士兵,则其子节点y可放可不放,取最优值.

    初始化:(f[x][0]=0,f[x][1]=1)

    目标:(min(f[root][0],f[root][1]))

    //#include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    inline int read(){
       int s=0,w=1;char ch=getchar();
       while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
       while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
       return s*w;
    }
    const int N=1505;
    struct ppx{
        int num,son[N];
    }a[N];
    int bj[N],f[N][2];
    inline void dp(int x){
        f[x][0]=0;f[x][1]=1;//初始化
        for(int i=1;i<=a[x].num;i++){
    		int y=a[x].son[i];
    		dp(y);//树形DP一般都是先往下走,再更新
    		f[x][0]+=f[y][1];
    		f[x][1]+=min(f[y][0],f[y][1]);
        }
    }
    int main(){
        int n;
        while(~(scanf("%d",&n))){
    		memset(bj,0,sizeof(bj));//初始化
    		for(int i=1,x;i<=n;i++){
    	    	x=read();a[x].num=read();
    	    	for(int j=1,y;j<=a[x].num;j++){
    				y=read();a[x].son[j]=y;
    				bj[y]++;
    	    	}
    		}
    		int root=0;while(bj[root])root++;//找根
    		dp(root);
    		printf("%d
    ",min(f[root][0],f[root][1]));
        }
        return 0;
    }
    
    
  • 相关阅读:
    线性方程组迭代法
    统计学习方法——朴素贝叶斯法、先验概率、后验概率
    信息熵、相对熵(KL散度)、交叉熵、条件熵
    六级听力词组积累
    样本均值和样本方差的无偏性证明、样本方差的方差
    Python 矩阵相关
    Python 绘图
    win10、VSCode、python3数据科学库
    Python杂记
    Gradient descend 梯度下降法和归一化、python中的实现(未完善)
  • 原文地址:https://www.cnblogs.com/PPXppx/p/10989868.html
Copyright © 2011-2022 走看看