zoukankan      html  css  js  c++  java
  • hdu 1011 树形dp+背包

    题意:有n个房间结构可看成一棵树,有m个士兵,从1号房间开始让士兵向相邻的房间出发,每个房间有一定的敌人,每个士兵可以对抗20个敌人,士兵在某个房间对抗敌人使无法走开,同时有一个价值,问你花费这m个士兵可以得到的最大价值是多少

    链接:点我

    分析:树形dp,对于点u,dp[u][j]表示以u为根的树消耗j个士兵得到的最大值,dp[i][j]=max(dp[i][j],dp[i][j-k]+dp[son][k]+val[u])

    注意是无向图,vis位置不能随便放,且注意dp不能直接+val,因为这样根节点就加不到val了

    虽然方程很快就想出来了,真写起来wa点还是很多的

    第二次做

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<queue>
     7 #include<map>
     8 using namespace std;
     9 #define MOD 1000000007
    10 const int INF=0x3f3f3f3f;
    11 const double eps=1e-5;
    12 typedef long long ll;
    13 #define cl(a) memset(a,0,sizeof(a))
    14 #define ts printf("*****
    ");
    15 const int MAXN=601;
    16 int n,m,tt;
    17 int aa[MAXN];
    18 int tot,head[MAXN],dp[MAXN][MAXN],in[MAXN];
    19 int bug[MAXN],val[MAXN],vis[MAXN];
    20 struct Edge
    21 {
    22     int to,next;
    23 }edge[MAXN<<2];
    24 void addedge(int u,int v)
    25 {
    26     edge[tot].to=v;
    27     edge[tot].next=head[u];
    28     head[u]=tot++;
    29 }
    30 void dfs(int u)
    31 {
    32     vis[u]=1;
    33     int num=(bug[u]+19)/20;
    34     for(int i=num;i<=m;i++) dp[u][i]=val[u];
    35     for(int i=head[u];i!=-1;i=edge[i].next)
    36     {
    37         int v=edge[i].to;
    38         if(vis[v])  continue;
    39         dfs(v);
    40         for(int j=m;j>=num;j--)
    41         {
    42             for(int k=1;j-k>=num;k++)    //派k人攻打其他地方
    43             {
    44                 dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]);
    45             }
    46         }
    47     }
    48 }
    49 void init()
    50 {
    51     tot=0;
    52     memset(head,-1,sizeof(head));
    53     cl(dp);
    54     cl(vis);
    55 }
    56 int main()
    57 {
    58     int i,j,k;
    59     #ifndef ONLINE_JUDGE
    60     freopen("1.in","r",stdin);
    61     #endif
    62     while(scanf("%d%d",&n,&m)!=EOF)
    63     {
    64         if(n==-1&&m==-1)  break;
    65         init();
    66         for(i=1;i<=n;i++)
    67         {
    68             scanf("%d%d",&bug[i],&val[i]);
    69         }
    70         int u,v;
    71         for(i=1;i<=n-1;i++)
    72         {
    73             scanf("%d%d",&u,&v);
    74             addedge(u,v);
    75             addedge(v,u);
    76         }
    77         if(m==0)
    78         {
    79             printf("0
    ");
    80             continue;
    81         }
    82         dfs(1);
    83         printf("%d
    ",dp[1][m]);
    84     }
    85 }
  • 相关阅读:
    [转]Oracle 语法之 OVER (PARTITION BY ..) 及开窗函数
    oracle本月、上月、去年
    Oracle 物理视图刷新报错ORA-00942
    [转]Oracle trunc()函数的用法
    [转]物化视图创建 及 刷新机制修改
    [转]oracle制定定时任务(dbms_jobs)
    【转】Windows平台下的Subversion安装配置新手指南
    【转】数字签名与数字证书
    [转]SQL 常用函数及示例
    【转】视图、索引、存储过程 、触发器、游标及事务
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4277271.html
Copyright © 2011-2022 走看看