dp优化专辑 A - Starship Troopers [dp+背包]

来源:互联网 发布:淘宝促销日期 编辑:程序博客网 时间:2024/05/22 15:03

题意:

有n个房间组成一棵树,你有m个士兵,从1号房间开始让士兵向相邻的房间出发,每个房间里有一个brain,每一个士兵可以消灭20个bugs,求可以获得的最大brain


分析:

树形01背包,树用邻接表存储,深度优先遍历该树~dp[i][j]表示在i结点,放j个人所获得的最大值


//AC CODE:

#include<iostream>#include<cmath>#include<algorithm>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<map>using namespace std;const int maxn=220;struct Node{    int number,p;} node[maxn];int n,m;bool vis[maxn];int dp[maxn][maxn];//dp[i][j]表示在i结点,放j个人所获得的最大值int adj[maxn][maxn];//邻接表void dfs(int k){    vis[k]=true;    int num=(node[k].number+19)/20;    for(int i=num; i<=m; i++)        dp[k][i]=node[k].p;    for(int i=1; i<=adj[k][0]; i++)    {        int u=adj[k][i];        if (vis[u])//别忘了剪枝            continue;//        dfs(u);        //关键部分 01 package        for(int j=m; j>=num; j--)            for(int l=1; l+j<=m; l++)                dp[k][j+l]=max(dp[k][j+l],dp[k][j]+dp[u][l]);    }}int main(){    while(scanf("%d%d",&n,&m)&&(n!=-1&&m!=-1))    {        memset(vis,false,sizeof(vis));        memset(dp,0,sizeof(dp));        memset(adj,0,sizeof(adj));        for(int i=1; i<=n; i++)            scanf("%d%d",&node[i].number,&node[i].p);        int b,e;        for(int i=1; i<n; i++)//用邻接表存树        {            scanf("%d%d",&b,&e);            adj[b][0]++;            adj[b][adj[b][0]]=e;            adj[e][0]++;            adj[e][adj[e][0]]=b;        }        if(m==0)            printf("0\n");        else        {            dfs(1);            printf("%d\n",dp[1][m]);        }    }}


原创粉丝点击