hdu1561 The more, The Better(常见分组背包+树形dp)

来源:互联网 发布:美女公寓小说txt淘宝 编辑:程序博客网 时间:2024/05/19 15:42

题意:中文题意。

思路:分析完后题意后,攻击先后顺序就是一个有向边,每条边权值1,这个城堡能直接攻击就把他和0点相连。那么这就是一个在树上分组背包的题目。

设:dp[i][j]表示在i点已经攻击了j个城堡的最大值。 dp[i][j]=max(dp[i][j-k]+dp[v][k]); v是i的子节点。

注意多了一个0点后,相当于多了一个城堡。

#include<bits/stdc++.h>using namespace std;template<int N,int M>//N点的个数,M边的个数struct Graph{    int top;    struct Vertex{        int head;    }V[N];    struct Edge{        int v,next;    }E[M];    void init(){        memset(V,-1,sizeof(V));        top = 0;    }    void add_edge(int u,int v){        E[top].v = v;        E[top].next = V[u].head;        V[u].head = top++;    }};const int maxn=200+10;Graph<maxn,maxn*2> g;int n,m,dp[maxn][maxn],val[maxn],vis[maxn];void dfs(int u){   dp[u][1]=val[u];   for(int i=g.V[u].head;i!=-1;i=g.E[i].next){      int v=g.E[i].v;      dfs(v);      for(int j=m+1;j>=1;j--){        for(int k=1;k<j;k++){          dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]);        }      }   }}int main(){    while(~scanf("%d%d",&n,&m)&&n&&m){       g.init();       val[0]=0;       for(int i=1;i<=n;i++){          int a,b;scanf("%d%d",&a,&val[i]);          g.add_edge(a,i);       }       memset(dp,0,sizeof(dp));       dfs(0);       printf("%d\n",dp[0][m+1]);    }}


0 0
原创粉丝点击