为率封臣们南下打击兰尼斯特家族的嚣张气焰,罗柏·史塔克决定举行一场宴会来提升封臣们的士气。史塔克家族的分封关系可以抽象成一颗树,共n个封臣。根节点为史塔克家。除史塔克家外的所有封臣均有且仅有一个直属的上级。由于经费有限,罗柏·史塔克只能邀请一部分封臣来参加宴会。经费上限用w来描述。另外,对于第i个封臣,在宴会中满足他的需要需要Ci元,所产生的士气为ei。还有一个重要的限制,就是任何封臣不希望和他的任何上级一起进行宴会,这会让他们感到拘谨。一个封臣的上级包含他的直属上级及所有间接的上级,即在这个“分封树”上从该封臣走到根的路径上所有的节点(包括根)。
现在,罗柏·史塔克希望在预算之内,所有人产生的士气最大。请你完成他的任务。
输入
单组测试数据。第一行为n(1<=n<=1200)和w(1<=w<=1000),第二行为封臣2到n的直属上级fi(即父节点),第三行为1到n的ci,第四行为1到n的ei。(1<=ci,ei<=1000) 数字间用一个空格隔开。
输入保证封臣编号按照分封树的层次关系进行,即fi一定小于i。
输出
输出一个数,代表最大的士气值。
样例输入
10 100
1 2 2 1 4 3 5 6 1
12 53 127 32 164 22 199 10 19 17
-1 0 3 5 7 -2 9 6 8 13
样例输出
27
#include<iostream> #include<cstdio> #include<cstring> #include<vector> using namespace std; #define max(a,b) a>b?a:b int dp[1210][1010][2]; int ci[1210],ei[1210]; vector<int>g[1210]; int n,w; void dfs(int t) { if(ci[t]<w) for(int i=ci[t];i<=w;i++) dp[t][i][1]=ei[t]; for(int i=0;i<g[t].size();i++) { dfs(g[t][i]); for(int k=w;k>=0;k--) for(int j=1;j<=k;j++) { int temp=dp[t][k-j][0]+(max(dp[g[t][i]][j][1],dp[g[t][i]][j][0]));//max()外面不加括号会出错!什么鬼 dp[t][k][0]=max(dp[t][k][0],temp); } } } int main() { int t; cin>>n>>w; for(int i=2;i<=n;i++) { cin>>t; g[t].push_back(i); } for(int i=1;i<=n;i++) { cin>>ci[i]; } for(int i=1;i<=n;i++) { cin>>ei[i]; } memset(dp,0,sizeof(dp)); dfs(1); cout<<(max(dp[1][w][1],dp[1][w][0]))<<endl; return 0; }