HDU 1011 树形dp
2015-04-05 15:40
274 查看
//运行时间 2683 MS
#include<iostream> #include<algorithm> #include<vector> #include<cstdio> #include<cstring> using namespace std; struct Vertex{ int v; Vertex* next; }vertex[215]; Vertex* head[102]; int men,n,men_needed[102],brains[102],a,b,dp[102][102],cnt; bool visited[102]; void link(int a,int b){ vertex[++cnt].v = b; if(head[a]==NULL) { head[a] = &vertex[cnt]; vertex[cnt].next = NULL; } else { vertex[cnt].next = head[a]; head[a] = &vertex[cnt]; } } int R[102][102]; int solve(int i,int men_left){ if(R[i][men_left]) return R[i][men_left]; if(men_left<men_needed[i]||men_left==0) return 0; //注意 <span style="font-family: Arial, Helvetica, sans-serif;">men_left==0 的情况时返回0 ,</span><span style="font-family: Arial, Helvetica, sans-serif;"> 虽然有时候不需要士兵去战斗,但需要士兵去拿brains </span>
visited[i] = true; int men_left0 = men_left; men_left-=men_needed[i]; Vertex* p = head[i]; int Max=-1; int dp[2][men_left+1],k=1; memset(dp,0,sizeof(dp)); while(p!=NULL) { if(men_left<men_needed[p->v]||visited[p->v]) { p = p->next; continue; } for(int men=0;men<=men_left;men++) { //给当前 分支 总共分配 men 个士兵 dp[k][men] = 0; for(int j=0;j<=men;j++){ //给当前 p->v 分配 j 个 dp[k][men] = max( dp[k][men] , dp[!k][men-j] + solve(p->v,j) ); } } p = p->next; k = !k; } visited[i] = false; R[i][men_left0] = brains[i] + dp[!k][men_left]; return brains[i] + dp[!k][men_left]; } int main(){ while(scanf("%d%d",&n,&men)!=EOF&&(n!=-1||men!=-1)){ memset(visited,0,sizeof(visited)); memset(R,0,sizeof(R)); cnt = -1; for(int i=0;i<102;i++) head[i] = NULL; for(int i=1;i<=n;i++){ scanf("%d%d",&men_needed[i],&brains[i]); if(men_needed[i]>0) men_needed[i]=(men_needed[i]-1)/20+1; } for(int i=1;i<n;i++){ scanf("%d%d",&a,&b); link(a,b); link(b,a); } printf("%d\n",solve(1,men)); } }
上面的代码效率不够高。
//运行时间 93 MS
#include <iostream> #include <cstdio> #include <cmath> #include <cstdlib> #include <string> #include <cstring> #include <algorithm> #include <iomanip> using namespace std; const int inf = 0x7FFFFFFF; const int maxn = 111; struct node{ int v; node *next; }tree[maxn<<1], *head[maxn]; int ptr,n,sum; int dp[105][2005], bug[105], w[105]; bool vis[105]; void AddEdge(int a,int b){ tree[ptr].v=a; tree[ptr].next=head[b]; head[b]=&tree[ptr++]; } int DFS(int cnt,int M){ if(M==0) return 0; int m=M-bug[cnt]; vis[cnt]=true; node *p=head[cnt]; int Max=0; while(p!=NULL){ if(vis[p->v]){ p = p->next; continue; } for(int i=m ; i>=bug[p->v] ; --i){ dp[p->v][i]=DFS(p->v,i); //cout<<p->v<<' '<<i<<"=="<<dp[p->v][i]<<endl; } for(int i=m;i>=bug[p->v];--i) // i 为士兵个数 for(int j=i;j>=bug[p->v];--j) dp[cnt][i]=max( dp[cnt][i] , dp[cnt][i-j]+dp[p->v][j] ); p=p->next; } //cout<<cnt<<' '<<m<<"=="<<dp[cnt][m]<<endl; return w[cnt]+dp[cnt][m]; } int main(){ int a=inf+1; int m; while(~scanf("%d%d",&n,&m)&&!(n==-1&&m==-1)){ ptr=1; for(int i=1;i<=n;++i){ int a; scanf("%d%d",&a, w+i); bug[i]=(a%20)?1:0; bug[i]+=a/20; //if(bug[i]==0) bug[i]=1; } memset(head,0,sizeof(head)); for(int i=1;i<n;++i){ int a,b; scanf("%d%d",&a,&b); AddEdge(b,a); AddEdge(a,b); } if(m<bug[1]){ puts("0"); continue; } memset(dp,0,sizeof(dp)); memset(vis,false,sizeof(vis)); int ans=DFS(1,m); printf("%d\n",ans); } return 0; }
相关文章推荐
- hdu 1011 Starship Troopers(树形DP)
- hdu 1011 ,hdu 1561,树形DP
- hdu 1011 Starship Troopers (树形背包dp)
- HDU 1011 Starship Troopers (树形DP)
- HDU 1011 Starship Troopers(树形DP)
- hdu 1011 Starship Troopers(树形DP)
- hdu 1011 Starship Troopers 树形dp
- hdu 1011 Starship Troopers 树形dp
- hdu 1011 树形DP
- hdu 1011 Starship Troopers(树形DP+背包问题)
- hdu 1011 Starship Troopers(树形dp)
- hdu 1011 树形DP
- hdu 1011(树形dp)Starship Troopers
- hdu 1011 Starship Troopers(树形DP)
- HDU 1011 Starship Troopers 树形DP(0-1背包)
- HDU 1011 Starship Troopers - 01树形dp 有坑啊!!
- HDU 1011 Starship Troopers---树形dp+有依赖的背包
- hdu 1011 树形dp 背包
- HDU-1011 树形dp
- HDU 1011 Starship Troopers 树形DP(0-1背包)