随笔-68  评论-10  文章-0  trackbacks-0

树形背包。代码如下:

#include<iostream>
#include
<vector>
using namespace std;
int n,m;
int num[105],brain[105];
int dp[105][105];
int vis[105];
vector
<int> map[105];

int max(int a,int b)
{
    
return a>b?a:b;
}

void dfs(int u)
{
    
int i,j,k;
    vis[u]
=1;
    
int tt=(num[u]+19)/20;
    
for(i=tt;i<=m;i++)
        dp[u][i]
=brain[u];
    
for(i=0;i<map[u].size();i++)
    
{
        
int temp=map[u][i];
        
if(vis[temp]) continue;
        dfs(temp);
       
for(j=m;j>=tt;j--)
           
for(k=1;k<=m;k++)
          
{
               
if(j-k>=tt)
                  dp[u][j]
=max(dp[u][j],dp[u][j-k]+dp[temp][k]);
          }

    }

}

int main()
{
    
while(scanf("%d%d",&n,&m)!=EOF&&(m!=-1||n!=-1))
    
{
        
int i,u,v;
        
for(i=1;i<=n;i++)
            scanf(
"%d%d",&num[i],&brain[i]);
        
for(i=1;i<=n;i++)
            map[i].clear();
        
for(i=1;i<n;i++)
        
{
            scanf(
"%d%d",&u,&v);
            map[u].push_back(v);
            map[v].push_back(u);
        }


        memset(vis,
0,sizeof(vis));
        memset(dp,
0,sizeof(dp));
        
if(m==0)
        
{
            printf(
"0\n");
            
continue;
        }

        dfs(
1);
        printf(
"%d\n",dp[1][m]);
    }

    
return 0;
}


或者:
#include
<iostream>
#include
<vector>
using namespace std;
int n,m;
int num[105],brain[105];
int dp[105][105],f[105][105];
int vis[105];
vector
<int> map[105];

int max(int a,int b)
{
    
return a>b?a:b;
}


void dfs(int u)
{
    
int i,j,k;
    vis[u]
=1;
    
for(i=0;i<map[u].size();i++)
    
{
        
int temp=map[u][i];
        
if(vis[temp]) continue;
        dfs(temp);
        
for(j=m;j>=0;j--)  
            
for(k=1;k<=m;k++)  
 
/*此处须从1开始,因为不存在没人还往后继节点走的情况!(由于可能
    出现dp[temp][0]!=0的情况,如果此处k==0,则代表该分组不被选择的情
     况,在这种情况下却加上了一个不为0的dp[temp][0],显然矛盾。因此
     从1开始。如果要从0开始,dp[temp][0]应该等于0.)
*/

            
{                                  
                
if(j>=k)
                f[u][j]
=max(f[u][j],f[u][j-k]+dp[temp][k]);
            }

    }


    
int tt=(num[u]+19)/20;

    
for(i=tt;i<=m;i++)
            dp[u][i]
=f[u][i-tt]+brain[u];
}


int main()
{
    
while(scanf("%d%d",&n,&m)!=EOF&&(m!=-1||n!=-1))
    
{
        
int i,u,v;
        
for(i=1;i<=n;i++)
            scanf(
"%d%d",&num[i],&brain[i]);
        
for(i=1;i<=n;i++)
            map[i].clear();
        
for(i=1;i<n;i++)
        
{
            scanf(
"%d%d",&u,&v);
            map[u].push_back(v);
            map[v].push_back(u);
        }


        memset(vis,
0,sizeof(vis));
        memset(dp,
0,sizeof(dp));
        memset(f,
0,sizeof(f));
        
if(m==0)
        
{
            printf(
"0\n");
            
continue;
        }

        dfs(
1);
        printf(
"%d\n",dp[1][m]);
    }

    
return 0;
}


posted on 2010-08-07 01:25 wuxu 阅读(1321) 评论(0)  编辑 收藏 引用 所属分类: 动态规划

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理