邱老师玩游戏
Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
邱老师最近在玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中邱老师允许攻克M个城堡并获得里面的宝物。
但由于地理位置原因,有些城堡不能直接攻克,要攻克这些城堡必须先攻克其他某一个特定的城堡。你能帮邱老师算出要获得尽量多的宝物应该攻克哪M个城堡吗?
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
对于每个测试实例,输出一个整数,代表邱老师攻克M个城堡所获得的最多宝物的数量。
Sample input and output
Sample Input | Sample Output |
---|---|
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 |
5 13 |
思路:选的话肯定是选入度为0的城堡先,那么dp[i][j]表示以i城堡为起点跑j个城堡的最多宝物,dp1[i]表示i个城堡的最多宝物
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=302; 4 5 vector<int >e[N]; 6 int dp[N][N]; 7 int dp1[N]; 8 struct node{ 9 int x,y; 10 }a[N]; 11 int n,m; 12 13 void dfs(int u){ 14 dp[u][1]=a[u].y; 15 dp[u][0]=0; 16 for(int i=0;i<e[u].size();i++){ 17 int v=e[u][i]; 18 dfs(v); 19 for(int j=m;j>=2;j--){ 20 for(int k=1;k<=j;k++){ 21 dp[u][j]=max(dp[u][j],dp[u][k]+dp[v][j-k]); 22 } 23 } 24 } 25 } 26 int main(){ 27 while(scanf("%d%d",&n,&m)){ 28 if(n==0&&m==0) break; 29 memset(dp,0,sizeof(dp)); 30 memset(dp1,0,sizeof(dp1)); 31 for(int i=0;i<300;i++) e[i].clear(); 32 for(int i=1;i<=n;i++){ 33 scanf("%d%d",&a[i].x,&a[i].y); 34 if(a[i].x!=0) { 35 e[a[i].x].push_back(i); 36 } 37 } 38 for(int i=1;i<=n;i++){ 39 if(a[i].x==0) dfs(i); 40 } 41 // cout<<dp[1][1]<<" "<<dp[2][1]<<" "<<dp[3][1]<<endl; 42 for(int i=1;i<=n;i++){ 43 if(a[i].x==0){ 44 for(int j=m;j>=1;j--){ 45 for(int k=1;k<=j;k++) 46 dp1[j]=max(dp1[j],dp1[j-k]+dp[i][k]); 47 } 48 } 49 } 50 cout<<dp1[m]<<endl; 51 } 52 }