通向自由的鑰匙(key.pas/c/cpp)
通向自由的鑰匙被放n個房間裡,這n個房間由n-1 條走廊連線。但是每個房間裡都有
特別的保護魔法,在它的作用下,我無法通過這個房間,也無法取得其中的鑰匙。雖然我可
以通過消耗能量來破壞房間裡的魔法,但是我的能量是有限的。那麼,如果我最先站在 1
號房間(1 號房間的保護魔法依然是有效的,也就是,如果不耗費能量,我無法通過1號房
間,也無法取得房間中的鑰匙) ,如果我擁有的能量為p,我最多能取得多少鑰匙?
輸入資料
第一行包含兩個非負整數,第乙個為n,第二個為p。
接下來n 行 ,按1~n的順序描述了每個房間。 第i+1行包含兩個非負整數cost和 keys,
分別為第 i件房取消魔法需要耗費的能量和房間內鑰匙的數量。
接下來 n-1行,每行兩個非負整數 x,y,表示x 號房間和y 號是連通的。
輸出資料
一行乙個整數,表示取得鑰匙的最大值。
樣例 輸入:key.in
5 5
1 2
1 1
1 1
2 3
3 4
1 2
1 3
2 4
2 5
輸出: key.out 7
資料範圍
對於 20%的測試資料,有n<=20
對於 30%的測試資料,有n<=30
對於所有測試資料,有p,n<=100, cost <= maxint, keys<= maxint
一道較為基礎的樹形dp。
首先多叉轉二叉,然後再dp即可。
狀態:用f[i][j]表示i這顆子樹,使用j的能量能得到的最大鑰匙數。
轉移方程:f[i][j] = max(f[son[i]][k] + f[bro[i]][j - k - c[i]] + v[i], f[bro[i]][j])。
讀入邊的時候,首先讀成無向圖,再根據無向圖建樹,否則後果很嚴重;還有某個節點消耗的能量可以為0,所以j = 0並不能當作邊界條件。
accode:
#include #include #include #include using std::max;
const char fi = "key.in";
const char fo = "key.out";
const int maxn = 110;
const int maxm = 110;
const int max = 0x3fffff00;
const int min = -max;
struct edge ;
edge *edge[maxn];
int f[maxn][maxm];
int bro[maxn];
int son[maxn];
int c[maxn];
int v[maxn];
int n, m;
void init_file()
void insert(int u, int v)
void readdata()
}int dp(int i, int j)
return f[i][j];
} void build(int u, int last)
}} void work()
int main()
NKOI 1469 通向自由的鑰匙
通向自由的鑰匙 time limit 10000ms memory limit 65536k total submit 96 accepted 39 case time limit 1000ms description 通向自由的鑰匙被放n個房間裡,這n個房間由n 1條走廊連線。但是每個房間裡都有特...
NKOI 1469 通向自由的鑰匙
p1469通向自由的鑰匙 時間限制 10000 ms 空間限制 65536 kb 問題描述 通向自由的鑰匙被放n個房間裡,這n個房間由n 1條走廊連線。但是每個房間裡都有特別的保護魔法,在它的作用下,我無法通過這個房間,也無法取得其中的鑰匙。雖然我可以通過消耗能量來破壞房間裡的魔法,但是我的能量是有...
NKOI 1469 通向自由的鑰匙
p1469通向自由的鑰匙 時間限制 10000 ms 空間限制 65536 kb 問題描述 通向自由的鑰匙被放n個房間裡,這n個房間由n 1條走廊連線。但是每個房間裡都有特別的保護魔法,在它的作用下,我無法通過這個房間,也無法取得其中的鑰匙。雖然我可以通過消耗能量來破壞房間裡的魔法,但是我的能量是有...