标签:
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 17498 Accepted Submission(s): 4644
/* 这个必须要用无向图,重判的时候用visit数组标记 */ #include<stdio.h> #include<iostream> #include<string.h> #include<vector> #define N 110 using namespace std; int n,m; vector<int> v[N];//用来存放数的 int dp[N][N];//dp[i][j]表示在第i个结点的时候,用j个士兵能获得多少幽灵 int f[N];//用来找树根的 bool visit[N];//记录当前结点走没走过 struct node { int p,q;//妖怪的数量,想要的有幽灵的数量 }fr[N]; void dfs(int root) { visit[root]=true; int num=(fr[root].p+19)/20;//当前房间最少需要 for(int i=num;i<=m;i++) dp[root][i]=fr[root].q;//只要是超过了num个士兵都是q个人 //cout<<num<<endl; for(int i=0;i<v[root].size();i++) { int next=v[root][i];//下一个房间 //cout<<"next="<<next<<endl; //cout<<"visit[next]="<<visit[next]<<endl; if(visit[next]) { //cout<<"visit[next]="<<visit[next]<<endl; continue;//下一步走过了就跳过 } dfs(next); //cout<<"ok"<<endl; //对dp数组进行初始化 for(int j=m;j>=num;j--)//背包枚举 { for(int k=1;k+j<=m;k++) { if(dp[next][k]) dp[root][j+k]=max(dp[root][j+k],dp[root][j]+dp[next][k]); } } } } int main() { //freopen("in.txt","r",stdin); while(scanf("%d%d",&n,&m)!=EOF) { if(n==-1&&m==-1) break; memset(visit,false,sizeof visit); memset(dp,0,sizeof dp); v[0].clear(); for(int i=1;i<=n;i++) { scanf("%d%d",&fr[i].p,&fr[i].q); //cout<<fr[i].p<<" "<<fr[i].q<<endl; //f[i]=i; v[i].clear(); } v[n+1].clear(); int a,b; for(int i=1;i<n;i++) { scanf("%d%d",&a,&b); //cout<<a<<" "<<b<<endl; v[a].push_back(b); v[b].push_back(a); f[b]=a; } //for(int i=1;i<=n;i++) // cout<<"i="<<i<<" "<<v[i].size()<<endl; if(m==0) { printf("0\n"); } else { //int root=1; //while(root!=f[root]) root=f[root];//找根 //cout<<"root="<<root<<endl; dfs(1); printf("%d\n",dp[1][m]); } } return 0; }
hdu 1011 Starship Troopers(树形DP入门)
标签:
原文地址:http://www.cnblogs.com/wuwangchuxin0924/p/5781943.html