hdu 1561 The more,The BetterツリーDP+リュックサック
2394 ワード
The more, The Better
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3511 Accepted Submission(s): 2056
Problem Description
ACboyは戦略ゲームが大好きで、1つの地図の上で、Nつの城があって、すべての城はすべて一定の宝物があって、毎回ゲームの中でACboyはMつの城を攻略して中の宝物を得ることを許可します.しかし、地理的な理由で、直接攻略できない城もあります.これらの城を攻略するには、まず他の特定の城を攻略しなければなりません.できるだけ多くの宝物を手に入れるにはどのM城を攻略すべきか、ACboyに計算してもらえますか?
Input
各試験例は、まず、2つの整数、N、M.(1<=M<=N<=200)を含む.次のN行では、各行に2つの整数が含まれ、a,b.i行目では、aはi番目の城を攻略するにはまずa番目の城を攻略しなければならないことを表し、a=0であればi番目の城を直接攻略することができることを表す.bはi番目の城の宝物の数を表し、b>=0である.N=0でM=0入力が終了します.
Output
各試験例について、ACboyがM個の城を攻略して得た最も多くの宝物の数を表す整数を出力する.
Sample Input
Sample Output
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3511 Accepted Submission(s): 2056
Problem Description
ACboyは戦略ゲームが大好きで、1つの地図の上で、Nつの城があって、すべての城はすべて一定の宝物があって、毎回ゲームの中でACboyはMつの城を攻略して中の宝物を得ることを許可します.しかし、地理的な理由で、直接攻略できない城もあります.これらの城を攻略するには、まず他の特定の城を攻略しなければなりません.できるだけ多くの宝物を手に入れるにはどのM城を攻略すべきか、ACboyに計算してもらえますか?
Input
各試験例は、まず、2つの整数、N、M.(1<=M<=N<=200)を含む.次のN行では、各行に2つの整数が含まれ、a,b.i行目では、aはi番目の城を攻略するにはまずa番目の城を攻略しなければならないことを表し、a=0であればi番目の城を直接攻略することができることを表す.bはi番目の城の宝物の数を表し、b>=0である.N=0でM=0入力が終了します.
Output
各試験例について、ACboyがM個の城を攻略して得た最も多くの宝物の数を表す整数を出力する.
Sample Input
3 2
0 1
0 2
0 3
7 4
2 2
0 1
0 4
2 1
7 1
7 6
2 2
0 0
Sample Output
5
13
#include<stdio.h>
#include<string.h>
#define size 210
struct node{
int from,to,next;
}edge[size];
int head[size]; //head[i] i
int m,tot,n,a,b;
//
int dp[size][size],f[size][size],w[size],vis[size];
void addEdge(int fa,int ch)
{
edge[tot].from=fa; //
edge[tot].to=ch; //
edge[tot].next=head[fa]; //tot a
head[a]=tot++; //head[a]
}
int max(int a,int b)
{
return a>b?a:b;
}
void dfs(int u)
{
int i,j,k,r;
vis[u]=1;
for(i=head[u];i!=-1;i=edge[i].next)
{
r=edge[i].to;
if(!vis[r])
dfs(r);
for(j=m;j>=1;j--) //r , , f[u][j-k] r
{
for(k=1;k<=j;k++)
{
f[u][j]=max(f[u][j],f[u][j-k]+dp[r][k]);
}
}
}
for(i=m+1;i>=1;i--)
{
dp[u][i]=max(dp[u][i],f[u][i-1]+w[u]); // , dp[u]
}
}
int main()
{
int i,j,k,l;
while(scanf("%d %d",&n,&m)&&n||m)
{
memset(dp,0,sizeof(dp));
memset(head,-1,sizeof(head));
memset(f,0,sizeof(f));
memset(vis,0,sizeof(vis));
memset(w,0,sizeof(w));
tot=0;
for(i=1;i<=n;i++)
{
scanf("%d %d",&a,&b);
addEdge(a,i);
w[i]=b;
}
dfs(0);
printf("%d
",dp[0][m+1]);
}
return 0;
}