HDU-1561-A

来源:互联网 发布:数据恢复软件正式版 编辑:程序博客网 时间:2024/06/08 06:55

https://vjudge.net/contest/142381#problem/A
在树上进行背包。
一开始写错了,根据图的关系来进行01背包。
dp[a][i]=max(dp[a][i-1]+b[s],dp[a][i]);
在更近的节点,无法对该分支的数量进行背包。。如果这个分支只有部分解是最优的,那么就无法保存。。
方法1 :初始化为b[i]。
方法2 :初始化为0,最后再加上。。

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <vector>using namespace std;/*后根遍历,然后在树上用背包。*/const int maxn=2000;bool vis[maxn];int b[maxn];vector<int>G[maxn];void add(int a,int b){   G[a].push_back(b);    //G[b].push_back(a);}int n,m;int dp[maxn][maxn];int ans[maxn][maxn];int dfs(int a){   for(int i=0;i<G[a].size();i++)    {   int s=G[a][i];        if(!vis[s])        {  vis[s]=true;            dfs(s);           for(int x=m;x>=0;x--)            for(int k=0;k<=x;k++)        ans[a][x]=max(ans[a][x],ans[a][x-k]+dp[s][k]);        }    }     for(int i=1;i<=m+1;i++)       dp[a][i]=ans[a][i-1]+b[a];    return 0;}int main(){   int a;     while(~scanf("%d%d",&n,&m))     {   memset(ans,0,sizeof(ans));         if(n==0&&m==0) break;         for(int i=0;i<maxn;i++)            G[i].clear();         b[0]=0;         for(int i=1;i<=n;i++)         {   scanf("%d%d",&a,&b[i]);            add(a,i);         }           for(int i=0;i<=n;i++)            for(int j=0;j<=m+1;j++)              dp[i][j]=0;         memset(vis,false,sizeof(vis));         dfs(0);         /*for(int i=1;i<=n;i++)         {for(int j=0;j<=m;j++)           cout<<dp[i][j]<<" ";            cout<<endl;         }*/         cout<<dp[0][m+1]<<endl;     }    return 0;}
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <vector>using namespace std;/*后根遍历,然后在树上用背包。*/const int maxn=2000;bool vis[maxn];int b[maxn];vector<int>G[maxn];void add(int a,int b){   G[a].push_back(b);    //G[b].push_back(a);}int n,m;int dp[maxn][maxn];int dfs(int a){   for(int i=0;i<G[a].size();i++)    {   int s=G[a][i];        if(!vis[s])        {  vis[s]=true;            dfs(s);            for(int i=m+1;i>1;i--)            for(int k=1;k<=i;k++)        dp[a][i]=max(dp[a][i],dp[a][k]+dp[s][i-k]);        }    }        //for(int i=1;i<=m+1;i++)            //cout<<dp[a][i]<<"! ";         //cout<<endl;         //cout<<a<<endl;    return 0;}int main(){   int a;     while(~scanf("%d%d",&n,&m))     {   if(n==0&&m==0) break;         for(int i=0;i<maxn;i++)            G[i].clear();         b[0]=0;         for(int i=1;i<=n;i++)         {   scanf("%d%d",&a,&b[i]);            add(a,i);         }         /*for(int i=0;i<=n;i++)         {   cout<<i<<"!!";              for(int j=0;j<G[i].size();j++)                 cout<<G[i][j]<<" ";              cout<<endl;         }*/           for(int i=0;i<=n;i++)            for(int j=0;j<=m+1;j++)              {dp[i][j]=b[i];              dp[i][0]=0;              }         memset(vis,false,sizeof(vis));         dfs(0);         /*for(int i=1;i<=n;i++)         {for(int j=0;j<=m;j++)           cout<<dp[i][j]<<" ";            cout<<endl;         }*/         cout<<dp[0][m+1]<<endl;     }    return 0;}
原创粉丝点击