hdu 1011 starship troopers

来源:互联网 发布:最新数据库编程工具 编辑:程序博客网 时间:2024/05/23 18:29

这道题是一个树形 背包问题,或者说树形DP问题,房间的管道形成树。

背包问题的特点: 最优子结构,可分解,
解决办法: 常见的有递归(自顶向下),搜索(自底向上),背包注意的问题,为什么要自底向上搜索????

需要好好学习背包问题;

#include <iostream>#include<vector>#include<cstdio>#include<cstring>using namespace std;typedef struct{int enemy;int prop;}Node;Node room[103];vector<int> conn[103];int dp[103][103];// dp[i][j] store in the room i  ,cost  j soldiers  then get the propbool visited[103];int n,m;int max(int x,int y){    return x>y?x:y;}void dfs(int start){    int tmp=(room[start].enemy+19)/20;    // notice if here m=0 and tmp=0,  for example room=(0,20) but m=0 the result is 0 not 20    for(int i=tmp;i<=m;i++){        //under room start  ,cost soldier that greater than tmp, will get the prop of room start        dp[start][i]=room[start].prop;    }    visited[start]=true;    for(int i=0;i<conn[start].size();i++){        int next=conn[start][i];        if(visited[next]){            continue;        }        dfs(next);        // dp bag algorithm (bei bao)        for(int j=m;j>=tmp;j--){            //has cost tmp soldier            for(int k=1;k<=(j-tmp);k++){                dp[start][j]=max(dp[start][j-k]+dp[next][k],dp[start][j]);            }        }    }}int main(){    while(scanf("%d%d",&n,&m)){        if(n==m&&n==-1)            break;        for(int i=0;i<=n;i++){            conn[i].clear();        }        memset(dp,0,sizeof(dp));        memset(visited,false,sizeof(visited));        for(int i=1;i<=n;i++){            scanf("%d%d",&room[i].enemy,&room[i].prop);        }        int j=0,k=0;        for(int i=0;i<n-1;i++){            scanf("%d%d",&j,&k);            conn[j].push_back(k);            conn[k].push_back(j);        }        // handle input        // here is import if m==0, then althrough a room has 0 bug ,but 20 prop  but should 0        if(m==0){            cout<<0<<endl;            continue;        }        dfs(1);        cout<<dp[1][m]<<endl;    }    return 0;}
原创粉丝点击