HDU 1054 Strategic Game (树形DP)

来源:互联网 发布:怎么做好网络销售 编辑:程序博客网 时间:2024/04/30 15:55

题目点我点我点我


题目大意:在一棵树上的结点放置士兵,士兵可以本结点及相邻结点,问最少放置士兵数。


解题思路:树形DP


dp[i][0] 为以 i 为根节点,并且该点不放,所需要的最少的人数;

dp[i][1] 为以 i 为根节点,并且该点放,所需要的最少的人数。


那么状态转移方程为:


dp[i][0]=sum(dp[son[i][j]][1]) 该点不放的话,那么它的儿子节点必须都放,这样之间的边才可以被覆盖


dp[i][1]=sum(min(dp[son[i][j]][0],dp[son[i][j]][1])) 该点放的话,那么它的儿子节点就有两种决策,一种是放,一种是不放,取 min 就行了

这里的son[i][j]只是抽象表示i结点的儿子j。


/* ***********************************************┆  ┏┓   ┏┓ ┆┆┏┛┻━━━┛┻┓ ┆┆┃       ┃ ┆┆┃   ━   ┃ ┆┆┃ ┳┛ ┗┳ ┃ ┆┆┃       ┃ ┆┆┃   ┻   ┃ ┆┆┗━┓ 马 ┏━┛ ┆┆  ┃ 勒 ┃  ┆      ┆  ┃ 戈 ┗━━━┓ ┆┆  ┃ 壁     ┣┓┆┆  ┃ 的草泥马  ┏┛┆┆  ┗┓┓┏━┳┓┏┛ ┆┆   ┃┫┫ ┃┫┫ ┆┆   ┗┻┛ ┗┻┛ ┆************************************************ */#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <stack>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <bitset>using namespace std;#define rep(i,a,b) for (int i=(a),_ed=(b);i<=_ed;i++)#define per(i,a,b) for (int i=(b),_ed=(a);i>=_ed;i--)#define pb push_back#define mp make_pairconst int inf_int = 2e9;const long long inf_ll = 2e18;#define inf_add 0x3f3f3f3f#define mod 1000000007#define LL long long#define ULL unsigned long long#define MS0(X) memset((X), 0, sizeof((X)))#define SelfType intSelfType Gcd(SelfType p,SelfType q){return q==0?p:Gcd(q,p%q);}SelfType Pow(SelfType p,SelfType q){SelfType ans=1;while(q){if(q&1)ans=ans*p;p=p*p;q>>=1;}return ans;}#define Sd(X) int (X); scanf("%d", &X)#define Sdd(X, Y) int X, Y; scanf("%d%d", &X, &Y)#define Sddd(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)#define reunique(v) v.resize(std::unique(v.begin(), v.end()) - v.begin())#define all(a) a.begin(), a.end()typedef pair<int, int> pii;typedef pair<long long, long long> pll;typedef vector<int> vi;typedef vector<long long> vll;inline int read(){int ra,fh;char rx;rx=getchar(),ra=0,fh=1;while((rx<'0'||rx>'9')&&rx!='-')rx=getchar();if(rx=='-')fh=-1,rx=getchar();while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra*fh;}//#pragma comment(linker, "/STACK:102400000,102400000")const int maxn = 1505;struct Edge{    int to,nx;}edge[maxn*2];int head[maxn],dp[maxn][2],vis[maxn],cnt;void addedge(int u,int v){    edge[cnt] = Edge {v,head[u]};    head[u] = cnt++;    edge[cnt] = Edge {u,head[v]};    head[v] = cnt++;}void dfs(int x){    vis[x] = 1;    dp[x][1] = 1;    dp[x][0] = 0;    for(int i=head[x];i;i=edge[i].nx)    {        int v = edge[i].to;        if(!vis[v])        {            dfs(v);            dp[x][0] += dp[v][1];            dp[x][1] += min(dp[v][1],dp[v][0]);        }    }}int main(){//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);ios::sync_with_stdio(0);cin.tie(0);int n;while(~scanf("%d",&n))    {        MS0(dp);        MS0(vis);        MS0(head);        cnt = 1;        int root = -1;        for(int i=1;i<=n;i++)        {            int u,v,k;            scanf("%d:(%d)",&u,&k);            if(root==-1)root = u;            while(k--)            {                scanf("%d",&v);                addedge(u,v);            }        }        dfs(root);        int ans = min(dp[root][1],dp[root][0]);        printf("%d\n",ans);    }return 0;}



0 0
原创粉丝点击